Handler消息传递机制

Handler消息传递机制


出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,则可能导致线程安全问题。为了解决这个问题,Android制定了一条简单的规定:只允许UI线程(主线程)修改Activity里的UI组件。

稍微想一想,如果新启动的线程需要动态修改界面组件怎么办呢。这时候就需要借助于Handler的消息机制来实现了。


Handler类简介

为了解决新线程动态修改界面组件的问题,所以引入了Handler类。所以Handler类主要作用有两个:

  • 在新启动的线程中发送消息
  • 在主线程中获取、处理消息

我们只需重写Handler类中处理消息的方法。当新启动的线程发送消息的时候,该消息就会放到与它相关的MessageQueue(不难想到,一个新线程只需要有一个MessageQueue)。Handler会不断从MessageQueue中获取并处理消息,这样就会让我们重写的方法被回调了。

Handler类包含如下的方法用于发送、处理消息:

void handleMessage(Message msg)处理消息的方法。该方法通常用来重写
final boolean hasMessages(int what)检查消息队列中是否包含what属性为指定值的消息
final boolean hasMessages(int what , Object object)检查消息队列中是否包含what属性为指定值且object属性为指定对象的消息
Message obtainMessage()获取消息
sendEmptyMessage(int what)发送空消息
final boolean sendEmptyMessageDelayed(int what ,long delayMillis)多少毫秒之后发送空消息
final boolean sendMessage(Message msg)立即发送消息
finla boolean sendMessageDelayed(Message msg , long delayMillis) 多少毫秒之后发送消息


Handler获取,处理消息

上面提到Handler是得到消息,然后处理消息的一个类,而MessageQueue是一个消息队列。那么是不是还差一个把消息放入MessageQueue中和把消息拿出来交给Handler处理的一个类呢。所以引入了一个Looper类:

Looper的主要功能:
  • Looper负责管理MessageQueue,会不断从MessageQueue中取出消息,并将消息分给对应的Handler处理。
获得一个Looper对象

上面提到每个线程最多只需要一个MessageQueue,所以一个线程中最多只能有一个Looper对象。看一下Looper构造器源码:

private Looper(){
    mQueue = new MessageQueue();
    mRun = true;
    mThread = mThread.currentThread();
}

可以看到构造器是使用private修饰的,所以程序员不能通过new来创建一个Looper对象。所以Looper类提供了一个prepare()方法来创建一个Looper对象。prepare()方法的源码:

private static final void prepare(){
    if(sThreadLocal.get() != null)
        throw new RuntimeException("Only one Looper may be created per thread");
    sThreadLocal.set(new Looper());
}

从上面的源码可以看出,prepare()对象保证了每个线程最多只有一个Looper对象。

通过Looper对象分发消息给Handler

当获得一个Looper对象之后,我们现在应该做的就是通过Looper对象,向MessageQueue中取出消息然后分发给Handler。Looper提供了静态的loop()方法。loop()方法使用一个死循环不断取出MessageQueue中的消息,并将取出的消息分给该消息对应的Handle进行处理。

总结

Looper、MessageQueue、Handler各自的作用:
  • Looper : 每个线程只有一个Looper,它负责管理MessageQueue,会不断从MessageQueue中取出消息,并将消息分给对应的Handler处理
  • MessageQueue : 由Looper负责管理。
  • Handler : 他能把消息发送给Looper管理的MessageQueue,并负责处理Looper分给它的消息。
新线程中使用Handler的步骤
  1. 调用Looper的perpare()方法为当前创建Looper对象,创建Looper对象时,他的构造器会创建与之配套的MessageQueue。
  2. 有了Looper之后,创建Handler子类的实例,重写handleMessage()方法,该方法负责处理来自其他线程的消息。
  3. 调用Looper的loop()方法启动Looper。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值