一。总结
Looper有一个MessageQueue,用于封装消息循环。 Handler封装了消息投递,消息处理等的辅助类
二。分析
1.从Looper的用法开始分析
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); //(1)调用prepare mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); //(2)进入消息循环 } }
(11)prepare做了什么?
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); public static void prepare() {
if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); }
sThreadLocal.set(new Looper()); //(12)构造一个Looper,设置到线程本地变量中
}
(12)构造Looper对象
private Looper() { mQueue = new MessageQueue(quitAllowed); mRun = true; mThread = Thread.currentThread(); //得到当前线程 }
所以由(12)可知,prepare把Looper对象保存在线程本地变量中。巧妙地把Looper和调用线程关联起来。
2.Handler-MessageQueue-Looper,三者构成了死循环+消息通信的模型
public static void loop() { final Looper me = myLooper(); // (21)取得线程本地变量Looper if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; // 取出Looper中的queue // 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); //Handler target; 参照下面的dispatchMessage方法 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.recycle(); } } public static Looper myLooper() { //(22)返回线程本地变量Looper return sThreadLocal.get(); }
所以由(21)、(22)可看出loop()处理本线程消息队列中的消息。
三。Looper, Message,Handler之间的关系
1.Message中有个Handler,指定这个Message由哪个Handler处理
Handler target;
2.分析Handler成员变量
final MessageQueue mQueue; final Looper mLooper; final Callback mCallback;
3.Handler默认构造函数
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()); } } mLooper = Looper.myLooper(); //(31)获得调用线程的Looper if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; //(32)获得Looper中的消息队列 mCallback = null; }
4.Handler的另一个构造函数
public Handler(Looper looper) { //(33)传入某个线程的Looper mLooper = looper; mQueue = looper.mQueue; //(34)获得Looper中的消息队列
mCallback = null;
}
由上可知,Handler中的MessageQueue都会指向Looper中的消息队列。
5.There are two main uses for a Handler:
(1) to schedule messages and runnables to be executed as some point in the future;
(2) to enqueue an action to be performed on a different thread than your own.
Handler只有一个消息队列,即MessageQueue。通过post()传进去的Runnable将会被封装成消息对象后传入MessageQueue。当Looper轮询到该线程时,并不会单独开启一个新线程,
而Runnable仍然在当前Looper绑定的线程中执行,Handler只是调用了该线程对象的run()而已。通过post()将Runnable提交到主线程的Looper中可以实现UI的更新。
51.sendMessage
public boolean sendMessageAtTime(Message msg, long uptimeMillis){ boolean sent = false; MessageQueue queue = mQueue; if (queue != null) { msg.target = this; //(41)把处理这个message的Handler设为自己 sent = queue.enqueueMessage(msg, uptimeMillis); } else { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); } return sent; }
2.post
public final boolean post(Runnable r){ return sendMessageDelayed(getPostMessage(r), 0); } private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; ///*package */ Runnable callback; 将Runnable封装成消息对象 return m; } public final boolean sendMessageDelayed(Message msg, long delayMillis){ if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }
6.消息处理
public void handleMessage(Message msg) { //子类要重写的方法 } public void dispatchMessage(Message msg) { if (msg.callback != null) { //如果msg本身有callback handleCallback(msg); } else { if (mCallback != null) { //如果handler本身有callback if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); //最后交给子类处理 } }
7.msg的Callback
private static void handleCallback(Message message) { message.callback.run(); //直接调用Runnable的run方法,也就是说不是新建线程来执行 }