码迷,mamicode.com
首页 > 移动开发 > 详细

android handler、looper、message、messageQueue、

时间:2014-10-23 22:20:56      阅读:336      评论:0      收藏:0      [点我收藏+]

标签:android   style   color   ar   使用   strong   sp   数据   on   

一: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在同一个线程中) 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

     

android handler、looper、message、messageQueue、

标签:android   style   color   ar   使用   strong   sp   数据   on   

原文地址:http://www.cnblogs.com/liuluchao/p/4044665.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!