Message,MessageQueue,Handler和Looper的关系,Handler机制
1.关于Message,MessageQueue,Handler和Looper的关系:Looper不断的从MessageQueue中取出消息,交给Handler去处理,looper和线程绑定
来看一下这几个类的源码
参考Message 源码,其主要成员变量如下:
public final class Message implements Parcelable { public int what; public int arg1; public int arg2; public Object obj; public Messenger replyTo; public int sendingUid = -1; private static final Object sPoolSync = new Object(); private static Message sPool; private static int sPoolSize = 0; private static final int MAX_POOL_SIZE = 50; private static boolean gCheckRecycle = true; ....... }
这些成员变量中what用来保存消息标识,arg1和arg2是用来存放整型数据的,obj存储人员类型变量,replyTo是消息管理器,会关联到一个handler。通常使用Message.obtain获取message,避免创建多余对象节约内存,从源码看sPool为null时会自动new Message出来。
MessageQueue
public final class MessageQueue {
// True if the message queue can be quit.
private final boolean mQuitAllowed;
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
//构造方法,调用了native方法
mPtr = nativeInit();
}
//队列操作
boolean enqueueMessage(Message msg, long when) //入队
Message next() //出队
void removeMessages(Handler h, Runnable r, Object object) //根据Runable删除队列元素
void removeMessages(Handler h, int what, Object object) //根据Message.what删除队列元素
private void dispose() //销毁队列
.....
}
Handler的构造函数如下:
public Handler()
public Handler(Callbackcallback)
public Handler(Looperlooper)
public Handler(Looperlooper, Callbackcallback)
其主要成员变量如下
public class Handler { final MessageQueue mQueue; final Looper mLooper; final Callback mCallback; final boolean mAsynchronous; IMessenger mMessenger; ...... }
第1个和第2个构造函数都没有传递Looper,这两个构造函数都将通过调用Looper.myLooper()获取当前线程绑定的Looper对象,然后将该Looper对象保存到名为mLooper的成员字段中。
第3个和第4个构造函数传递了Looper对象,这两个构造函数会将该Looper保存到名为mLooper的成员字段中。
第2个和第4个构造函数还传递了Callback对象,Callback是Handler中的内部接口,需要实现其内部的handleMessage方法,其中Callback接口如下,该接口处理Message消息。因此处理Message消息有重写Handler的handleMessage方法或者在初始化Handler的时候传入一个Handler.CallBack接口,源码中优先判断Handler.CallBack是否为空
public interface Callback { /** * @param msg A {@link android.os.Message Message} object * @return True if no further handling is desired */ public boolean handleMessage(Message msg); }
把Message消息放入队列的方法如下:
public final boolean post(Runnable r)
public final boolean postDelayed(Runnable r, long delayMillis)
public final boolean sendMessage(Message msg)
public final boolean sendEmptyMessage(int what)
Looper
public final class Looper { static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); private static Looper sMainLooper; // guarded by Looper.class final MessageQueue mQueue; final Thread mThread; ...... }
注释中给出了looper的典型用法:
* <pre> * 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(); * } * }</pre> */
看一下Looper.prepare()和Looper.loop()具体做了什么
public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { //通过sThreadLocal.get()判断保证一个Thread只能有一个Looper实例 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } //new一个looper来初始化looper sThreadLocal.set(new Looper(quitAllowed)); }
private Looper(boolean quitAllowed) { //在looper的构造函数中创建MessageQueue mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }
再来看一下Handler是如何跟looper关联的:Handler中就持有一个Looper,Looper类提供myLooper()方法提供looper
//Looper中的myLooper()
public static @Nullable Looper myLooper() { return sThreadLocal.get(); }
//Handler构造函数 public Handler(Callback callback, boolean async) { ...... mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
//Looper类同时提供了获取UI线程looper的方法 getMainLooper()
/** * Returns the application's main looper, which lives in the main thread of the application. */ public static Looper getMainLooper() { synchronized (Looper.class) { return sMainLooper; } }
Looper.loop()创建处理消息的环境,循环处理消息。
public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(msg); if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } msg.recycleUnchecked(); } }
进入for循环后,开始从MessageQueue中取出一个消息(可能会阻塞),如果当前消息队列中没有Message,线程退出;否则分发消息。msg.target.dispatchMessage(msg)中的target就是一个Handler。最后消息处理完毕,进行回收。
为何主线程不需要调用Looper.looper和Looper.prepare
普通线程只要prepare就可以了,而主线程使用的是prepareMainLooper;普通线程生成一个与Looper绑定的Handler对象就行,而主线程是从当前线程中获取Handler(thread.getHandler())
我们看一下ActivityThread(UI线程)的源码,ActivityThread在应用程序启动的时候由系统创建出来
public static void main(String[] args) { ...... Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { //主线程获取Handler sMainThreadHandler = thread.getHandler(); } ...... Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
//初始化主线程的looper
public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } }
//给主线程提供looper
public static Looper getMainLooper() { synchronized (Looper.class) { return sMainLooper; } }
对于主线程,thread.getHandler()返回的就是mH
如上,一个thread通过sThreadLocal.get来保证只有一个looper,主线程在ActivityThread创建了一个Handler(mH),子线程通过Looper.myLooper获取looper。每个looper只对应一个MessageQueue,每个Message最多指定一个Handler来处理.Thread和Handle是一对多的关系.