Android消息处理机制系列文章整体内容如下
Android消息处理机制1——Handler
Android消息处理机制2——Message
Android消息处理机制3——MessageQueue
Android消息处理机制4——Looper
一 构造器
Handler的构造器有7种
1、public Handler()
2、public Handler(Callback callback)
3、public Handler(boolean async)
4、public Handler(Callback callback, boolean async){
//代码省略
mLooper = Looper.myLooper(); //会返回一个自己线程绑定的Looper,如果当前线程没有绑定Looper,就会返回null。
mQueue = mLooper.mQueue; //获取looper维护的queen队列
mCallback = callback;
//代码省略
}
5、public Handler(Looper looper, Callback callback)
6、public Handler(Looper looper)
7、public Handler(Looper looper, Callback callback, boolean async){
mLooper = looper;//可以绑定其他的looper实例
mQueue = looper.mQueue; //获取looper维护的queen队列
mCallback = callback;
}
使用编号为1、2、3的构造器创建handler实例,最终调用的构造器都是编号为4的构造器。
这个handler实例只能持有它所在线程的looper对象的引用
如果使用编号为5、6的构造器,最终调用的构造器是编号为7的构造器。它可以持有任意线程的looper对象的引用。
二 发送消息
消息发送有两个步骤:
- 构建message对象
- 将message发送到消息队列里面去
1、构建Message对象
将消息抽象成Message类,里面比较重要的属性有:
public int what; //用户定义的消息编码,让接收者能区分不同的消息,从而做出不同的处理
public int arg1; //int类型的数据
public int arg2; //int类型的数据
public Object obj; //任意类型的数据 是否把所有的obj都自动转化为Parcelable类型数据,obj也可以用来标识message,postAtTime(Runnable r, Object token, long uptimeMillis)方法就是用obj来标识message的
Handler target; //处理返回的message的handler实例
Runnable callback; //消息被处理的时候执行被执行的回调
下面的obtainMessage方法都会调用Message的obtain方法,会组装一个message对象。
public final Message obtainMessage()
public final Message obtainMessage(int what)
public final Message obtainMessage(int what, Object obj)
public final Message obtainMessage(int what, int arg1, int arg2)
public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
2、将message发送到消息队列
public final boolean post(Runnable r)
public final boolean postAtTime(Runnable r, long uptimeMillis)
public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
public final boolean postDelayed(Runnable r, long delayMillis)
上面四个postXX方法会先调用getPostMessage(Runnable r) 方法,将runnable封装成message。具体实现如下
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
组装的message没有what属性,也就没有办法针对不同的message采用不同的处理方法。
然后会调用下面的方法发送消息
public final boolean sendMessage(Message msg)
public final boolean sendMessageDelayed(Message msg, long delayMillis)
//下面三个方法会在方法内部组装一个 message
public final boolean sendEmptyMessage(int what)
public final boolean sendEmptyMessageDelayed(int what, long delayMillis)
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis)
上面的5个发送message的方法最终都会调用sendMessageAtTime方法
public boolean sendMessageAtTime(Message msg, long uptimeMillis){
MessageQueue queue = mQueue; //在构造handler对象的时候获取的, looper管理的消息队列
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);
}
public final boolean postAtFrontOfQueue(Runnable r)
会调用
public final boolean sendMessageAtFrontOfQueue(Message msg)
sendMessageAtFrontOfQueue这个方法其实就是将sendMessageAtTime的uptimeMillis设置为0
public final boolean sendMessageAtFrontOfQueue(Message msg) {
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, 0);
}
上面的所有发送消息的方法最终都会调用私有方法enqueueMessage(queue, msg, uptimeMillis),enqueueMessage又会调用MessageQueue的boolean enqueueMessage(Message msg, long when),将消息放入消息队列。
三 删除消息
public final void removeCallbacks(Runnable r) //根据runnable删除message
public final void removeCallbacks(Runnable r, Object token) //根据runnable和obj删除message,token最终会被组装成 message的obj属性
public final void removeMessages(int what) //根据what删除相关的message
public final void removeMessages(int what, Object object) //根据what和object删除相关的message
public final void removeCallbacksAndMessages(Object token) // 根据obj删除没有被处理的message,如果 token为null则会删除所有的message。
四 处理事件
由dispatchMessage根据message是否含有callback来将message交由handleCallback或者handleMessage来处理
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
//如果是调用postXX发送的消息则会执行handleCallback,handleCallback是私有方法,并且已经由handler实现了,用户不需要自己实现handleCallback方法
handleCallback(msg);
} else {
if (mCallback != null) {
//如果mCallback不为空,则执行mCallback的具体实现类里的handleMessage方法
if (mCallback.handleMessage(msg)) {
return;
}
}
//使用handler自己的handleMessage方法
handleMessage(msg);
}
}
dispatchMessage是在looper的loop()方法中调用的,用来分发message。
public static void loop(){
//省略代码
for(;;){
try {
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
}
//省略代码
}
(完)
网友评论