zoukankan      html  css  js  c++  java
  • android操作线程各种方法解析

    (一)刚开始学习android的时候我是这么写的

     1 new Thread( new Runnable() { public void run() { myView.invalidate(); } }).start(); 

    后来看到别的博客说这种违反android单线程模型 本人不理解非要刨根问题

    那么它是怎么违反单线程模型的呢?

    百度了一下找到了原因 如下

    一个 Android 程序开始运行时,就有一个主线程Main Thread被创建。该线程主要负责UI界面的显示、更新和控件交互,所以又叫UI Thread。由于只有UI线程更新界面所以说
    Android是单线程模型。   一个Android程序创建之初,一个Process呈现的是单线程模型--即Main Thread,在非主线程(UI线程)外调invalidate()刷新界面出现异常,即是说用其他的线程更新UI,android中是不被允许的

    例如:在非UI线程中调用invalidate会导致线程不安全,也就是说可能在非UI线程中刷新界面的时候,UI线程(或者其他非UI线程)也在刷新界面,这样就导致多个界面刷新的操作不能同步,导致线程不安全

    哦 那我明白了 如果这样写呢 涉及到多个非UI线程操作UI 会引起冲突 所以不建议这样写 但也不能一竿子打死吧 如果我这样写 不涉及到UI操作 例如我只是做http操作 获取数据库数据

    也会导致线程不安全嘛? 我个人觉得只要不涉及到UI操作 这样写也可以 所以android还是支持的

    (二)Thread+Handler

    发觉常用的方法是利用Handler来实现UI线程的更新的 大家都这么写

    我通常是这样写 自定义一个handler 和 Runnable 方便以后扩展

    /**
     * 自定义Handler
     * 
     * @author 龙塔
     *
     */
    public abstract class MyHandler extends Handler
    {
    	@Override
    	public void handleMessage(Message msg)
    	{
    		try
    		{
    			myHandleMessage(msg);
    		}
    		catch (Exception e)
    		{
    			e.printStackTrace();
    		}
    	}
    
    	protected abstract void myHandleMessage(Message msg) throws Exception;
    }
    

    /**
     *   自定义Runnable
     *   
     * @author 龙塔
     */
    public abstract class MyRunnable implements Runnable
    {
        @Override
        public void run()
        {
            try
            {
                myRun();
            }
            catch (Exception e)
            {
                 e.printStackTrace();
            }
        }
    
        protected abstract void myRun() throws Exception;
    }
    final MyHandler handler = new MyHandler()
            {
                @Override
                protected void myHandleMessage(Message msg) throws Exception
                {
                   
    } }; new Thread(new MyRunnable() { @Override protected void myRun() throws Exception { Looper.prepare(); dynamicTable = new DynamicTable(testActivity.this); Message message = handler.obtainMessage(); //测试方法
    message.obj
    = dynamicTable .loadTable(questionnaire); message.sendToTarget(); Looper.loop(); } }).start();
    }

    Handler来根据接收的消息,处理UI更新。Thread线程发出Handler消息,通知更新UI 参见了各种文档和api demo发现都是这样调用的

    这样调用应该万无一失了吧 呵呵

    (三)java习惯。Android平台中,这样做是不行的,这跟Android的线程安全有关  又是涉及到UI操作的 如果不是操作UI 这种方法我觉得可以用的

    在Android平台中需要反复按周期执行方法可以使用Java上自带的TimerTask类,TimerTask相对于Thread来说对于资源消耗的更低,除了使用Android自带的AlarmManager使用Timer定时器是一种更好的解决方法。 我们需要引入import java.util.Timer; 和 import java.util.TimerTask;

    public class JavaTimer extends Activity {  
      
        Timer timer = new Timer();  
        TimerTask task = new TimerTask(){   
            public void run() {  
                setTitle("hear me?");  
            }            
        };  
    
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.main);  
           
             timer.schedule(task, 10000);  
    
        }  
    }

    方法四:(TimerTask + Handler)  方法3的升级版

    错误写法 涉及到线程安全

    public class TestTimer extends Activity {  
      
        Timer timer = new Timer();  
        Handler handler = new Handler(){   
            public void handleMessage(Message msg) {  
                switch (msg.what) {      
                case 1:      
                    setTitle("hear me?");  
                    break;      
                }      
                super.handleMessage(msg);  
            }  
              
        };  
    
        TimerTask task = new TimerTask(){    
            public void run() {  
                Message message = new Message();      
                message.what = 1;      
                handler.sendMessage(message);    
            }            
        };  
    
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.main);  
          
            timer.schedule(task, 10000);  
        }  
    }

    正确写法 交由UI Thread处理

    import java.util.Timer;
    import java.util.TimerTask;
    import android.app.Activity;
    import android.os.Bundle;
    public class TestTimer extends Activity {
        Timer timer = new Timer();
        TimerTask task = new TimerTask(){
            public void run() {
                
                runOnUiThread(new Runnable(){
                @Override
                public void run() {
                    setTitle("hear me?");
                }});
                }
        };
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            timer.schedule(task, 10000);
        }
    }

    正确写法二 :由Handler处理UI 更新。

    package com.test;   
      
    import java.util.Timer;   
    import java.util.TimerTask;   
      
    import android.app.Activity;   
    import android.os.Bundle;   
    import android.os.Handler;   
    import android.os.Message;   
      
    public class TestTimer extends Activity {   
      
        Timer timer = new Timer();   
        Handler handler = new Handler(){   
      
            public void handleMessage(Message msg) {   
                switch (msg.what) {       
                case 1:       
                    setTitle("hear me?");   
                    break;       
                }       
                super.handleMessage(msg);   
            }   
               
        };   
        TimerTask task = new TimerTask(){   
      
            public void run() {   
                Message message = new Message();       
                message.what = 1;       
                handler.sendMessage(message);     
            }   
               
        };   
        public void onCreate(Bundle savedInstanceState) {   
            super.onCreate(savedInstanceState);   
            setContentView(R.layout.main);   
            timer.schedule(task, 10000);   
        }   
    }  

    在Android中还提供了一种有别于线程的处理方式,就是Task以及AsyncTask

    具体用法可以参见这个帖子

    http://blog.csdn.net/liuhe688/article/details/6532519

      

  • 相关阅读:
    Sql Server2000里面获得数据库里面所有的用户表名称 和对应表的列名称
    c#开发windows应用程序几个小技巧
    "Unexpected Error 0x8ffe2740 Occurred" Error Message When You Try to Start a Web Site
    注册asp.net到iis
    O/R Mapping 影射文件生成的一点研究(暂时放在这里,实现以后再进行总结)
    WMI使用集锦
    NHibernate快速指南
    项目打包以前需要删除的文件
    Asp.Net 学习资源列表
    精彩Blog
  • 原文地址:https://www.cnblogs.com/wangnannan/p/4651197.html
Copyright © 2011-2022 走看看