概念
- 什么是Android消息机制?
刚开始用时都会以为Android消息机制就是指Handler,因为在UI线程使用时都只需要Handler。其实,消息机制的组成不仅包括Handler,还包括Looper、MessegeQueue等。 - Android消息机制的作用?
2个作用:
1、代码逻辑转移。
可以是在线程内部也可以是在线程间转移。
用post(Runnable task)时,若task创建时所在的线程a和该Handler绑定的线程b不是同一个的话代码逻辑就线程a被转移到线程b中执行,若a、b是同一个线程的话代码逻辑的转移就只是在该线程内部。
用send方法时,若Handler创建时所在的线程a和该Handler绑定的线程b不是同一个的话代码逻辑就线程a被转移到线程b中执行,若a、b是同一个线程的话代码逻辑的转移就只是在该线程内部。
例子:IntentService中Handler将代码逻辑(即onHandleIntent()中的代码)从IntentService所在的线程即UI线程转移到IntentService中的HandlerThread这一线程中执行。
2、发送消息。
可以是在线程内部也可以在线程间发送消息。实际上也是代码逻辑的转移。
例子:子线程发送消息通知UI线程更改UI(即调用Handler的handleMesseage()方法,这是代码逻辑在线程内部转移)。
先上个图看下消息机制的大概原理:(是这篇文章的总结,很重要!!!,图比较小的可用浏览器新的标签页打开或下载下来)
看懂上图的你就已经掌握消息机制的一大半了,接下来我们结合源码逐个认识消息机制的组成成员,对每个类的介绍基本都是按照Field、Field的初始化、成员方法这一顺序来介绍的,嘻嘻。。。
Handler
作用:通过Handler的post、send方法发送一个Message(持有该Handler对象)到Handler关联的Looper的MessageQueue中。
关键:post、send方法。
1、 Handler中持有的Field(持有Loopper、MesseageQueue的对象)
final MessageQueue mQueue;
final Looper mLooper;//关联Looper,其实就是关联Looper所在的线程。
它们在构造方法中被赋值,看下面Handler的初始化。
2、 Handler的初始化
- 不指定Looper 的:handler = new Handler();
public Handler() {
this(null, false);
}
public Handler(Callback callback, boolean async) {
mLooper = Looper.myLooper();//默认使用当前线程的Looper。
if (mLooper == null) {
//Handler必须创建在有Looper的线程中。
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
UI线程中创建Handler一般就是用这种不用指定Looper,直接默认用当前UI线程的Looper。
- 指定Looper 的:handler = new Handler(looper);
public Handler(Looper looper) {
this(looper, null, false);
}
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
3、 Handler的使用
- post(Runnable r)
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
//将Runnable对象封装为Message对象
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;//Handler持有的MQ
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);
}
//调用MessageQueue的enqueueMessage()方法将message添加到它的队列中。
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(