应用程序入口:
ActivityThread类中
public static void main(String[] args) { Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); // End of event ActivityThreadMain. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
可以知道,程序初始化就会在主线程预加载MainLooper
public static void prepareMainLooper() { prepare(false); ... sMainLooper = myLooper(); } }
private static void prepare(boolean quitAllowed) { sThreadLocal.set(new Looper(quitAllowed)); }
public static @Nullable Looper myLooper() { return sThreadLocal.get(); }
以上就是Looper.prepareMainLooper()的过程,可以看出先在ThreLocal准备Looper对象,然后get Looper对象,先设置后获取再使用,不会为null
额外提一下ThreadLocal是个什么类?
* Implements a thread-local storage, that is, a variable for which each thread * has its own value. All threads share the same {@code ThreadLocal} object, * but each sees a different value when accessing it, and changes made by one * thread do not affect the other threads.就是说作用范围线程域,同一进程中的所有线程共享这个对象,但是每个线程根据其映射的值又不同
举个栗子,月亮只有一个,每个人中秋晚上赏月看到的月亮都不同
然后Looper进行loop()
public static void loop() { final Looper me = myLooper(); final MessageQueue queue = me.mQueue; 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; } msg.target.dispatchMessage(msg); msg.recycleUnchecked(); } }
看loop的过程,先得到消息队列queue=me.mQueue,这个队列是什么时候初始化的呢
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }是在给ThreadLocal绑定Looper时候初始化的。
既然消息队列有了,那就一个一个开始取吧,永真循环就开始了
当取到了消息之后,Handler就会分发消息dispatchMessage(msg)
岔开说一下,msg.target就是发送该消息的Handler对象
每一个轮询出来的消息都会持有一个发送该消息的引用,因为入队列时就保证了target不为null
源码在Handler中如下
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
回归主线,Hander分发消息
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
如果没有msg的Runnable任务或者Handler的回调,那么就会调用handleMessage(msg),这个方法就是调用者实现。
至此消息机制的整体流程讲完了。
有几个问题还要讲下:
1,既然是Looper一直在死循环,为何不引起阻塞,对性能有何影响
答案是linux的管道通信机制