Android中异步消息处理机制
- 函数内部变量。其作用区域是该函数,即每次调用该函数,该变量都会重新回到初始值。
- 类内部的变量。其作用就是该类所产生的对象,即只要该对象没有被销毁,则对象内部的变量则一直保持。
- 类内部的静态变量。其作用是整个进程,即只要在该进程中,该变量的值就会一直保持,无论使用多少类来构造这个对象,该变量只有一个赋值,且一直保持。
我们可以从类注释来了解Looper类的作用到底是干什么的。
Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call Most interaction with a message loop is through the This is a typical example of the implementation of a Looper thread, using the separation of class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
|
这里我们只从消息循环机制角度来分析这个Handler。首先看Handler的构造函数
/** * Default constructor associates this handler with the queue for the * current thread. * * If there isn‘t one, this handler won‘t be able to receive messages. */ public Handler() { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } //从TLS(局部线程存储)中取出已经存放好的Looper对象 mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can‘t create handler inside thread that has not called Looper.prepare()"); } //将Looper对象中的MessageQueue赋值给Handler中的对象 mQueue = mLooper.mQueue; mCallback = null; } |
sendMessage(...) -> sendMessageDelayed(...) -> sendMessageAtTime(...) 最终会通过sendMessageAtTime发送消息对象。 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { boolean sent = false; MessageQueue queue = mQueue; if (queue != null) { msg.target = this; //将消息对象加入到消息队列 sent = queue.enqueueMessage(msg, uptimeMillis); } else { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); } return sent; } 然后我们在来看看enqueueMessage进行了什么操作。 final boolean enqueueMessage(Message msg, long when) { ... if (needWake) { nativeWake(mPtr); } ... } nativeWake是一个java本地方法,这里涉及了消息机制中的Sleep-Wakeup机制,关于如何唤醒Looper线程的动作,这里不做赘述,其最终就是调用了 native层的Looper的wake函数,唤醒了这个函数之后,就开始进行消息循环 |
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。