Handler、Message、MessageQueue、 Looper、Handler Thread

简述:

  在Android中,我们必须在主线程中更新UI,若在子线程中更新UI或者主线程中完成耗时的工作,就会出现异常。面对这种情况,我们可以使用Handler、Message、MessageQueue、 Looper组成的异步消息处理机制解决。
  在这个机制中主要用到了消息循环(message loop)的结构。

通俗例子:

  想象应用是一间商店,闪电侠是员工(犹如应用里的线程),闪电侠可能要负责招待客户、布置商品、联系调货等工作。

  假如只有一个闪电侠,他要处理如打电话到其他店里调货的耗时任务,店里的顾客可能会等得不耐烦。
  要想解决问题,需要再雇佣一名闪电侠专门负责调货的工作。 即创建一个后台线程,然后通过该线程完成耗时任务。

  后台工作的闪电侠已结束调货任务。他需要将调货已完成的消息通知给前台工作的闪电侠。如果前台闪电侠非常忙碌,则后台闪电侠可能无法立即与他取得联系。
  他可以选择等到前台闪电侠空闲时再联系。这虽然可行,但效率不高。

  比较好的解决方案是为每个闪电侠提供一个收件箱。后台闪电侠写下调货已完成的信息,并将 其放置在前台闪电侠的收件箱顶部。而前台闪电侠如需告知后台闪电侠库存已空的信息,也可执行类似操作。

  有时,闪电侠可能需要及时完成某项任务,但当时并不方 便去做。这种情况下,他也可以在自己的收件箱放上一条提醒消息,然后在空闲的时候去完成它。

结构图分析:

结构图
  HandlerThread类是已经拥有Looper的方便Thread类。一般在onLooperPrepared()函数中写需要执行的内容。(普通线程是没有Looper的,直接new Handler会异常)

正常使用流程:

  1. 在带有Looper的线程中创建Handler对象,Handler对象内带有该Looper的引用。
  2. Handler调用方法发送Message对象(本质通过Looper,因为MessageQueue其实在Looper内),Message对象会添加到MessageQueue中。
  3. Looper会一直从MessageQueue中取出Message对象,最后分发回发送该Message对象的Handler的handlerMessage()方法中处理。

      一个Handler仅与一个Looper相关联,多个Handler可与同一个Looper相关联。一个Message也仅与一个目标Handler相关联。 Looper拥有着整个Message队列。


Handler类:

  Handler用于发送(sendMessage()方法)和处理Message(handleMessage()方法)。

  Handler允许你发送和处理与线程对应MessageQueue相关联的Message对象和Runnable对象。每一个Handler实例与只与一个线程和该线程的MessageQueue相关联。当你创建一个新的Handler对象时,它便与创建它的线程及MessageQueue绑定在一起。从那时候起,它会发送Message对象或Runnable对象到那个绑定了的MessageQueue处,然后当Message对象或Runnable对象从MessageQueue中被取出的时候,Handler会对它们进行处理。
  
  Handler有两个主要用途:
1. 安排Message对象或Runnable对象在某个未来的时间点被处理。
2. 通过在其他线程中的MessageQueue中放入Message,使行为在其他线程中完成。

关键成员:
  final MessageQueue mQueue;
  final Looper mLooper;
关键方法:
obtainMessage()      //从公共循环池里获取消息。比创建新实例有效率

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException( 
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis); // 最终调用了mQueue的enqueueMessage()方法
    }

Message类:

  Message类的对象可以在内部携带信息
  
  public int what; 用户定义的int型消息代码,用来描述消息;
  public Object obj; 随消息发送的用户指定对象;
  /package/ Handler target; 处理消息的Handler。
  
  Message在创建时,会自动与一个Handler相关联。 Message在准备处理状态下, Handler是负责让消息处理行为发生的对象。


Looper类:

  Looper是用来为一个Thread对象运行消息循环的。默认的线程是没有消息循环的。我们也可以为Thread创建一个Looper,在线程中调用Looper.prepare()来启动loop,然后调用loop()使之处理messages。
  

class LooperThread extends Thread{
      public Handler mHandler;

      publicvoid run(){
          Looper.prepare();

          mHandler =new Handler(){
              publicvoid handleMessage(Message msg){
                  // process incoming messages here
              }
          };

          Looper.loop();
      }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值