您的位置:首页 > 移动开发 > Android开发

Handler消息传递机制

2015-12-15 15:37 302 查看

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的步骤

调用Looper的
perpare()
方法为当前创建Looper对象,创建Looper对象时,他的构造器会创建与之配套的MessageQueue。

有了Looper之后,创建Handler子类的实例,重写
handleMessage()
方法,该方法负责处理来自其他线程的消息。

调用Looper的
loop()
方法启动Looper。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息