先看android提供的一个关于Handler、Looper使用的最简单范例:
class LooperThread extends Thread {//线程类,在这个线程中会启用消息分发机制
public Handler mHandler;
//启动线程时会调用线程的run()方法
public void run() {
Looper.prepare(); //创建属于该线程的looper,looper中含messageQueue对象
//创建handler用于发送消息,并传递Callback接口中handlerMessage方法的实现,Callback只有一个接口方法)
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
//启动loop()死循环,读取消息(可能阻塞)-dispatch-读取消息
Looper.loop();
}
}
第一部分:Looper.prepare()
每个线程只能有一个Looper对象,所以只能调用一次Looper.prepare。创建的Looper对象保存在线程间各自私有的本地存储区(TLS:Thread Local Stroage)。代码中体现在Looper有个sThreadLocal成员变量,创建后通过它获取该线程的looper对象。获取之前,必须先创建,创建调用Looper.prepare()静态方法,获取调用Looper.myLooper()静态方法。
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
89 public static void prepare() {
90 prepare(true);
91 }
92
93 private static void prepare(boolean quitAllowed) {
94 if (sThreadLocal.get() != null) {//每个线程只允许执行一次该方法
95 throw new RuntimeException("Only one Looper may be created per thread");
96 }//创建Looper对象,并保存在TLS中
97 sThreadLocal.set(new Looper(quitAllowed));
98 }
看看Looper的构造函数
216 private Looper(boolean quitAllowed) {
217 mQueue = new MessageQueue(quitAllowed);//创建MessageQueue对象
218 mThread = Thread.currentThread();//调用Looper.prepare()的线程
219 }
70 MessageQueue(boolean quitAllowed) {
71 mQuitAllowed = quitAllowed;//是否允许调用MessageQueue.quit()方法
72 mPtr = nativeInit();//jni调用到native层做啥?
73 }
Looper.prepare():创建Looper对象并保存在ThreadLocalStorage区域,构造Looper时又创建了MessageQueue对象。
第二部分 启动死循环Looper.loop():读取消息-分发消息-读取消息
129 public static void loop() {
130 final Looper me = myLooper();//获取本线程的looper对象
131 if (me == null) {//调用Looper.loop()之前必须先调用Looper.prepare()方法
132 throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
133 }
134 final MessageQueue queue = me.mQueue;//Looper中的MessageQueue对象
135
136 // Make sure the identity of this thread is that of the local process,
137 // and keep track of what that identity token actually is.
138 Binder.clearCallingIdentity();
139 final long ident = Binder.clearCallingIdentity();
140
141 for (;;) {//死循环
142 Message msg = queue.next(); //MessageQueue读取message, 可能阻塞?
143 if (msg == null) {
144 // No message indicates that the message queue is quitting.
145 return;
146 }
147
148 // This must be in a local variable, in case a UI event sets the logger
149 final Printer logging = me.mLogging;
150 if (logging != null) {
151 logging.println(">>>>> Dispatching to " + msg.target + " " +
152 msg.callback + ": " + msg.what);
153 }
154
155 final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
156
157 final long traceTag = me.mTraceTag;
158 if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
159 Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
160 }
161 final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
162 final long end;
163 try {
164 msg.target.dispatchMessage(msg);//获取message后,分发message给其target: Handler对象
165 end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
166 } finally {
167 if (traceTag != 0) {
168 Trace.traceEnd(traceTag);
169 }
170 }
171 if (slowDispatchThresholdMs > 0) {
172 final long time = end - start;
173 if (time > slowDispatchThresholdMs) {
174 Slog.w(TAG, "Dispatch took " + time + "ms on "
175 + Thread.currentThread().getName() + ", h=" +
176 msg.target + " cb=" + msg.callback + " msg=" + msg.what);
177 }
178 }
179
180 if (logging != null) {
181 logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
182 }
183
184 // Make sure that during the course of dispatching the
185 // identity of the thread wasn't corrupted.
186 final long newIdent = Binder.clearCallingIdentity();
187 if (ident != newIdent) {
188 Log.wtf(TAG, "Thread identity changed from 0x"
189 + Long.toHexString(ident) + " to 0x"
190 + Long.toHexString(newIdent) + " while dispatching to "
191 + msg.target.getClass().getName() + " "
192 + msg.callback + " what=" + msg.what);
193 }
194
195 msg.recycleUnchecked();//msg重利用,重置并加入消息池,在需要消息时可以直接从消息池中获取,不用每次都new
196 }
197 }
分发消息:直接分发消息给target(Handler对象),target可能是一个继承自Handler并重写了handlerMessage()方法的子类,
也可能不继承Handler,构造Handler对象时传入Callback接口对象,Callback接口只有一个handlerMessage方法需实现。
target在dispather消息时优先级如下:msg.callback.run;Callback接口对象方法mCallback.handlerMessage;自身HandlerMessage()方法。
msg.target.dispatchMessage(msg)
99 public void dispatchMessage(Message msg) {
100 if (msg.callback != null) {//第一优先级:msg.callback: Runnable对象
101 handleCallback(msg);//其实现为msg.callback.run()
102 } else {
103 if (mCallback != null) {
104 if (mCallback.handleMessage(msg)) {//第二优先级,Callback mCallback,接口实现
105 return;//无需继承Handler,构造Handler对象时传入Callback接口实现对象,Callback唯一接口方法handleMessage
106 }
107 }
108 handleMessage(msg);//继承了Handler对象并重写handlerMessage
109 }
110 }
消息重利用:消息处理完之后,放入消息池,创建消息对象时推荐使用Message.obtain()方法,优先从消息池中获取,消息池没有在new一个message。
msg.recycleUnchecked()
293 void recycleUnchecked() {//回收消息
294 // Mark the message as in use while it remains in the recycled object pool.
295 // Clear out all other details.
296 flags = FLAG_IN_USE;//处于消息池中,需置in_use
297 what = 0;
298 arg1 = 0;
299 arg2 = 0;
300 obj = null;
301 replyTo = null;
302 sendingUid = -1;
303 when = 0;
304 target = null;
305 callback = null;
306 data = null;
307
308 synchronized (sPoolSync) {//加入消息池,栈方式
309 if (sPoolSize < MAX_POOL_SIZE) {
310 next = sPool;//this.next---->sPool:
311 sPool = this;
312 sPoolSize++;
313 }
314 }
315 }
获取消息
124 public static Message obtain() {
125 synchronized (sPoolSync) {
126 if (sPool != null) { //先看消息池中是否有消息
127 Message m = sPool;//获取栈顶消息
128 sPool = m.next;
129 m.next = null;
130 m.flags = 0; // clear in-use flag,出消息池,清除in_use flag
131 sPoolSize--;
132 return m;
133 }
134 }//消息池无消息,new一个
135 return new Message();
136 }
第三部分 Handler创建及发送消息
最开始的范例代码中,是直接new一个Handler对象,并只传入Callback对象,没有传入Looper对象(则使用当前线程的looper对象,即创建Handler之前需要调用Looper.prepare() )。
133 public Handler(Callback callback) {
134 this(callback, false);
135 }
194 public Handler(Callback callback, boolean async) {
195 if (FIND_POTENTIAL_LEAKS) {
196 final Class<? extends Handler> klass = getClass();
197 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
198 (klass.getModifiers() & Modifier.STATIC) == 0) {
199 Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
200 klass.getCanonicalName());
201 }
202 }
203
204 //Handler中有个Looper成员变量
205 mLooper = Looper.myLooper();//获取当前线程的Looper
206 if (mLooper == null) {
207 throw new RuntimeException(
208 "Can't create handler inside thread that has not called Looper.prepare()");
209 }
210 mQueue = mLooper.mQueue;//Looper中有个MessageQueue对象
211 //Callback接口类型,只有一个handMessage接口需要实现
212 //可以继承Handler,并实现其handMessage方法,或不继承,构造handler时传入一个Callback接口对象
213 mCallback = callback;
214 mAsynchronous = async;
215 }
Handler发送消息之前,会获取一个消息,方法如下:
290 public final Message obtainMessage()
291 {
292 return Message.obtain(this);//Message.target=this
293 }
301 public final Message obtainMessage(int what)
302 {
303 return Message.obtain(this, what);//message.what
304 }
315 public final Message obtainMessage(int what, Object obj)
316 {
317 return Message.obtain(this, what, obj);//message.obj
318 }
329 public final Message obtainMessage(int what, int arg1, int arg2)
330 {
331 return Message.obtain(this, what, arg1, arg2);//message.arg1, message.arg2
332 }
344 public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
345 {
346 return Message.obtain(this, what, arg1, arg2, obj);
347 }
Handler.post(Runnable r)发送消息
sendMessage(msg):将消息插入触发时间小于等于current time + 0的所有pending消息之后
sendMessageDelayed(msg, delayMillos):将消息插入触发时间小于等于current time + delayMillis的所有pending消息之后
sendMessageAtTime(msg, updateMillos):将消息插入触发时间小于等于updateMillis的所有pending消息之后
Empty Message是值只指定what属性的消息
sendMessageAtFrontOfQueue(msg): 插入消息到对头,消息触发时间是0,下一个loop循环就会被处理,可能引起时序问题
postXxxx(Runnable): 先获取消息getPostMessage(Runnable),再调用对应的sendMessageXxxx()方法
code:
360 public final boolean post(Runnable r)//设置消息的Runnable成员变量callback,dispath消息时第一优先级运行该Runnable对象
361 {
362 return sendMessageDelayed(getPostMessage(r), 0);
363 }
781 private static Message getPostMessage(Runnable r) {
782 Message m = Message.obtain();
783 m.callback = r;
784 return m;
785 }
786
787 private static Message getPostMessage(Runnable r, Object token) {
788 Message m = Message.obtain();
789 m.obj = token;
790 m.callback = r;
791 return m;
792 }
383 public final boolean postAtTime(Runnable r, long uptimeMillis)
384 {//uptimeMillis:Runnable对象运行的绝对时间
385 return sendMessageAtTime(getPostMessage(r), uptimeMillis);
386 }
408 public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
409 {//token: msg.obj
410 return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
411 }
432 public final boolean postDelayed(Runnable r, long delayMillis)
433 {//delayMillis:延时delayMillis时间后,Runnable对象才运行,如果还未触发该消息就Looper.quit(),则消息会丢掉,Runnable对象不被执行
434 return sendMessageDelayed(getPostMessage(r), delayMillis);
435 }
452 public final boolean postAtFrontOfQueue(Runnable r)
453 {
454 return sendMessageAtFrontOfQueue(getPostMessage(r));
455 }
541 public final boolean sendMessage(Message msg)
542 {
543 return sendMessageDelayed(msg, 0);
544 }
553 public final boolean sendEmptyMessage(int what)
554 {
555 return sendEmptyMessageDelayed(what, 0);
556 }
557
558 /**
559 * Sends a Message containing only the what value, to be delivered
560 * after the specified amount of time elapses.
561 * @see #sendMessageDelayed(android.os.Message, long)-
562 *-
563 * @return Returns true if the message was successfully placed in to the-
564 * message queue. Returns false on failure, usually because the
565 * looper processing the message queue is exiting.
566 */
567 public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
568 Message msg = Message.obtain();
569 msg.what = what;
570 return sendMessageDelayed(msg, delayMillis);
571 }
583 public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
584 Message msg = Message.obtain();
585 msg.what = what;
586 return sendMessageAtTime(msg, uptimeMillis);
587 }
601 public final boolean sendMessageDelayed(Message msg, long delayMillis)
602 {
603 if (delayMillis < 0) {
604 delayMillis = 0;
605 }
606 return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
607 }
628 public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
629 MessageQueue queue = mQueue;
630 if (queue == null) {
631 RuntimeException e = new RuntimeException(
632 this + " sendMessageAtTime() called with no mQueue");
633 Log.w("Looper", e.getMessage(), e);
634 return false;
635 }
636 return enqueueMessage(queue, msg, uptimeMillis);
637 }
651 public final boolean sendMessageAtFrontOfQueue(Message msg) {
652 MessageQueue queue = mQueue;
653 if (queue == null) {
654 RuntimeException e = new RuntimeException(
655 this + " sendMessageAtTime() called with no mQueue");
656 Log.w("Looper", e.getMessage(), e);
657 return false;
658 }
659 return enqueueMessage(queue, msg, 0);
660 }
662 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
663 msg.target = this;
664 if (mAsynchronous) {//设置消息的同步属性,特定场景下,messageQueue中可能会引入同步屏障,在满足某个条件之前阻止同步消息的发送,异步消息发送不受影响。
665 msg.setAsynchronous(true);
666 }
667 return queue.enqueueMessage(msg, uptimeMillis);
668 }
剩余:MessageQueue native操作部分,MessageQueue.next() may block,MessageQueue.enqueueMessage
参考:Android消息机制1-Handler(Java层)