android handler、looper、message、messageQueue、

一:handler,looper,message,messagequeue,thread

handler: 消息处理着,负责Message消息的发送(handler.sendMessage(....))以及处理消息,对于handler处理消息则需要实现handlerMessage(Message msg)该方法,通过该方法处理特定的消息,例如ui的更细

looper:消息泵,用来从messageQueue中抽取消息,所以一个looper对应一个messageQueue;

message:消息,message中含有该消息的ID以及消息处理对象或者处理的数据,通过messageQueue消息队列同一处理。

messageQueue,消息队列,messageQueue中保存 通过handler发送来的消息,当然该保存不是真正意义上保存,而是以链式结构将消息链接起来。等待looper的抽取

thread:线程,负的调度整个消息循环,即消息循环的场所执行

 

二:handler、looper、messageQueue之间的关系

      looper与messageQueue是一一对应的关系,及创建一个looper的同时创建一个messageQueue,handler与它们只是简单的聚合关系,handler中会引用当前线程中的looper与messageQueue,从这里可以看出对个handler 能够同时处理一个looper与messageQueue,前提是这些handler都在同一个线程中

 

三:简单实例:

     消息的生成:

  Message msg=Handler.obtiainMessage();

  msg.what=what;

  msg.sendToTarget();

   消息发送:    

  

   
  MessageQueue queue=looper.myQueue();

//通过该对象找到与之对应的消息队列messageQueue

if(queue!=null){
  msg.target=this  

     sent = queue.enqueueMessage(msg, uptimeMillis);

}

注:在handler的sendMessageAtTme(Message msg,long time)中可以看出handler 找到自己线程中的MessageQueue中的message 然后将message的target设置为handler自己,目的是message能够找到正确的handler

 

 三:抽取

 //得到handler所在线程中的looper对象;
   Looper looper=handler1.getLooper();

//通过该对象找到与之对应的消息队列messageQueue
  MessageQueue queue=looper.myQueue();

   while (true) {

            Message msg = queue.next();   //不断的从消息队列中获取消息 

            if (msg != null) {

                if (msg.target == null) {

                    return;

                }

                msg.target.dispatchMessage(msg);

                msg.recycle();

            }

        }

从这里我们可以看出 不断的从消息队列中获取消息,然后通过message的target中携带的信息去,寻找正确的handler  用来处理该消息

四:处理:

 

  handler = new Handler(){

     复写handlerMessage(Message msg);

     }  

至此,我们看到,一个Message经由Handler的发送,MessageQueue的入队,Looper的抽取,又再一次地回到Handler的怀抱。而绕的这一圈,也正好帮助我们将同步操作变成了异步操作。

 

 小实例:跟新UI

首先在主线程中如果我们使用handler不创建looper对象,则系统会默认使用主线程中已经创建好的looper对象,然而在非ui线程中我们使用handler而不传入looper对象,则这个handler不能接受消息。

通常的做法是:

  Thread thread = new Thread() {

   @Override
   public void run() {

//创建handler之前我们需要首先准备一个looper


    Looper.prepare();
    Handler handler = new Handler() {

     @Override
     public void handleMessage(Message msg) {
      // TODO Auto-generated method stub
      super.handleMessage(msg);
     }

    };
    super.run();
   }

  };

//将该looper启动(跑起来)这样就能够从messageQueue中抽取message   这样handler才能正常运行
  Looper.loop();
  thread.start();

 }

 

注:handler 处理消息总是在创建该handler的线程中运行,而我们的消息处理中,不乏更新UI的操作,不正确的线程直接更新UI将引发异常,因此我们需要实时注意handler所在的线程。

 

小结:

  • handler 的处理运行是在创建该handler的线程中运行
  • 一个looper对应一个messageQueue
  • 一个线程对应一个looper
  • 一个looper可以对应多个handler(这些handler在同一个线程中) 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

     

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。