android Handler消息原理详情
Message对象
Message对象是需要被执行的对象,Message实例对象取得,通常使用Message类里的静态方法obtain(),该方法有多个重载版本,它创建并不一定创建一个新的Message实例,会有返回之前回收回来的对象。
Message Queue中存放着多个Message消息,是消息的管理者,每个线程。有且只有一个实例
Looper对象
每一个Looper对象和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象,创建一个Looper对象时,会同时创建一个MessageQueue对象。除了主线程有默认的Looper,会同时创建一个MessageQueue对象。除了主线程有默认的Looper,其它线程默认是没有MessageQueue对象的。所以不能接受Message。如需要接受,自己定义一个Looper对象,这样的该线程就有了自己的Looper对象和MessageQueue数据结构。
Looper从MessageQueue中取出Message然后,交由Handler的HandlerMessage进行处理。处理完成后,调用Message.recycle()将其放入MessagePool中。
Handler对象
消息处理者,handler负责将需要传递的信息封装成Message,通过调用ObtainMessage()来实现;
将消息传递给MessageQueue,然后通过转线程Looper通过MessageQueue获取Message消息,并将其通过dispatchMessage发送出去
创建Handler对象
1 public Handler(Callback callback, boolean async) { 2 mLooper = Looper.myLooper(); 3 if (mLooper == null) { 4 throw new RuntimeException( 5 "Can't create handler inside thread that has not called Looper.prepare()"); 6 } 7 mQueue = mLooper.mQueue; 8 mCallback = callback; 9 mAsynchronous = async; 10 }
获取当前线程的Looper
public static @Nullable Looper myLooper() { return sThreadLocal.get(); } public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); }
Message创建对象
public static Message obtain() { synchronized (sPoolSync) { if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null; m.flags = 0; // clear in-use flag sPoolSize--; return m; } } return new Message(); }
Message销毁对象
void recycleUnchecked() { // Mark the message as in use while it remains in the recycled object pool. // Clear out all other details. flags = FLAG_IN_USE; what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; sendingUid = -1; when = 0; target = null; callback = null; data = null; synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { next = sPool; sPool = this; sPoolSize++; } } }
发送消息
Handler发送消息的方式有二种:
1. sendMessage
2. Post(Runnable)
sendMessage消息是在HandlerMessage方法中执行
Post消息是在message.callback.run();方法中执行
1 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { 2 MessageQueue queue = mQueue; 3 if (queue == null) { 4 RuntimeException e = new RuntimeException( 5 this + " sendMessageAtTime() called with no mQueue"); 6 Log.w("Looper", e.getMessage(), e); 7 return false; 8 } 9 return enqueueMessage(queue, msg, uptimeMillis); 10 } 11 12 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { 13 msg.target = this; 14 if (mAsynchronous) { 15 msg.setAsynchronous(true); 16 } 17 return queue.enqueueMessage(msg, uptimeMillis); 18 }
线程消息执行
1 public static void loop() { 2 final Looper me = myLooper(); 3 if (me == null) { 4 throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); 5 } 6 final MessageQueue queue = me.mQueue; 7 8 // Make sure the identity of this thread is that of the local process, 9 // and keep track of what that identity token actually is. 10 Binder.clearCallingIdentity(); 11 final long ident = Binder.clearCallingIdentity(); 12 13 for (;;) { 14 Message msg = queue.next(); // might block 15 if (msg == null) { 16 // No message indicates that the message queue is quitting. 17 return; 18 } 19 20 final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs; 21 22 final long traceTag = me.mTraceTag; 23 if (traceTag != 0 && Trace.isTagEnabled(traceTag)) { 24 Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); 25 } 26 final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis(); 27 final long end; 28 try { 29 msg.target.dispatchMessage(msg); 30 end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis(); 31 } finally { 32 if (traceTag != 0) { 33 Trace.traceEnd(traceTag); 34 } 35 } 36 msg.recycleUnchecked(); 37 } 38 }
Handler执行线程
当Handler的mCallback有设置时优化执行,否则执行Handler的handleMessage函数
/** * Handle system messages here. */ public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
//Post消息执行 private static void handleCallback(Message message) { message.callback.run(); }
结论: