Handler机制

来源:互联网 发布:js alert弹出html代码 编辑:程序博客网 时间:2024/06/12 18:48

          做android的都知道Handler机制在面试中是常客,但由于android自身对handler的实现方式(在ActivityThread中实现了 ),所以大家平时可能都会用,但是一说到handler机制的时候可能会想什么鬼,handler不是子线程更新主线程时用的吗?有什么机制?不错,在android中是更新主线程时常用的,确切的说是异步消息机制,用于多线程通讯。android从子线程更新主线程起始就是用handler从子线程向UI主线程发送了一条消息。

     网上关于源码以及子线程与Ui线程的讲解已经很多了,我这里则不以子线程向UI线程通讯作为例子,我直接用两个线程通信介绍一下。因为我觉的对于刚开始没深入了解Handler的同学来讲,讲解Handler时还是尽量避开UI线程,搞不好越说越乱,我当年就是一片混乱。先看一下类的组成:

                                                                                                            

    忽略activity,我们现在有两个线程One和Two,试想发送一条信息应该怎么操作?你可能说我定义一个全局变量啊。好吧,那一千条呢?下面我以考驾照举例:你学习科目二很久了,现在要参加科目二考试了。去了后你发现有两个地方,备考大厅(ThreadOne)和考试场地(ThreadTwo)。备考大厅会有人员安排考生一个个考试,但是考试要到场地去考(不能再备考大厅)。所以备考大厅安排某某去考试,并一个个通知场地人员考生正式开始考试。这事如果放在android中算是耗时操作了吧。

    大致情形就是这样线程One告诉线程Two某某去场地考试了,线程Two收到消息后安排某某开始考试。没毛病吧?那么这是怎么一个消息呢,怎么处理呢?你们可以想想有哪些方式,但我只说handler机制怎么实现。进入主题:

    先介绍一下登场嘉宾:Thread(男主角) Handler(女主角)Looper, MessageQueue, Message(配角)

             首先看两段代码:

代码1:class ThreadTwo extends Thread{        @Override        public void run() {        //执行的代码        }        }

代码2:class ThreadTwo extends Thread{        @Override        public void run() {        Looper.prepare();        //执行的代码        Looper.loop();        }        }
         很明显,下面多了两行代码。但是别小瞧这两行代码,大家都知道,线程是执行完当前代码就完成使命了,线程的任务也就结束了,这样的话,其它线程给它发消息它就接收不到了(因为它死了)。那么怎么才能保证时刻接收消息,轮询听过吧?大概就是这样,给线程添加个消息循环,不断读取消息就行了。而looper就是这个作用,通过prepare()和loop()使线程进入循环。这样就可以不断读取消息了。消息从哪里循环读取呢?——MessageQueue。那MessageQueue的消息哪里来?——handler通过post或send方法传过来的。这样一个完整的消息循环就出来了,看个完整的例子吧:

public class HandlerActivity extends Activity {    private String TAG="HandlerActivityLog";        @Override        protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ThreadTwo two=new ThreadTwo();        two.start();//记住先运行two。否则handler会null的        ThreadOne t=new ThreadOne();        t.start();        }                class ThreadOne extends Thread{        @Override        public void run() {        //handler.getLooper().quit();        Message msg;        int total=1;        while(total<10){        msg=new Message();        msg.arg1=total;        handler.sendMessage(msg);        try {sleep(1000);//模拟等待} catch (InterruptedException e) {e.printStackTrace();}        total++;        }        }        }                private Handler handler=null;        class ThreadTwo extends Thread{@Override        public void run() {        Looper.prepare();        handler=new Handler(){        @Override        public void handleMessage(Message msg) {        super.handleMessage(msg);        //通过send方法传递的消息在这里处理;比如handler.sendEmptyMessage()        Log.d(TAG, msg.arg1+"号考生开始考试!");        }        };        Looper.loop();        }        }}

      接下来请其实ThreadTwo就相当于UI主线程,它用来接收另一个线程给它的消息(只是这个线程不是它的子线程)。

    总结:handler通过post或者send发送一个消息Message——MessageQueue将消息放入队列——looper循环读取

    ps:1.handler在new Handler(Looper looper)时默认不传递参数,获取的是当前线程的looper

       2.handler的post和send方法:

         send发送一条消息,在public void handleMessage(Message msg) {}中回调

         post一个Runnable对象,直接执行Runnable下的方法。

         比如:

         

handler.postDelayed(new Runnable() {@Overridepublic void run() {}}, 1000);


0 0
原创粉丝点击