一定搞懂Handler消息處理機制系列之「Handler消息發送」
Handler消息發送的方式有兩種:
-
Post
public final boolean post(Runnable r){ return sendMessageDelayed(getPostMessage(r), 0); } /** @param delayMillis 這個參數表示延遲多少毫秒之后觸發回調接口 */ public final boolean postDelayed(Runnable r, long delayMillis){ return sendMessageDelayed(getPostMessage(r), delayMillis); } /** 此方法會把產生的Message直接放入消息隊列中的首位,官方不建議使用該方法,因為這樣操作容易使消息隊列匱乏,導致排序問題或具有其他意外的副作用 */ public final boolean postAtFrontOfQueue(Runnable r){ return sendMessageAtFrontOfQueue(getPostMessage(r)); } /** @param uptimeMillis 這個參數表示當前時間為uptimeMillis毫秒時觸發回調接口 */ public final boolean postAtTime(Runnable r, long uptimeMillis){ return sendMessageAtTime(getPostMessage(r), uptimeMillis); } public final boolean postAtTime(Runnable r, Object token, long uptimeMillis){ return sendMessageAtTime(getPostMessage(r, token), uptimeMillis); }
我們可以看到,每個Post方法有一個共同的參數,那就是接收了一個Runnable接口,這個參數是用于回調的。每個使用Post發送消息時都去調用了sendMessage的相關方法,每個sendMessage相關方法都需要一個Message對象,所以就拿著Runnable對象去調用getPostMessage方法,
private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }; private static Message getPostMessage(Runnable r, Object token) { Message m = Message.obtain(); m.obj = token; m.callback = r; return m; };
getPostMessage會返回一個Message對象,拿到Message對象去調用相關sendMessage方法。
-
Send
public final boolean sendMessage(Message msg){ return sendMessageDelayed(msg, 0); }; public final boolean sendEmptyMessage(int what){ return sendEmptyMessageDelayed(what, 0); }; /** @param uptimeMillis 這個參數表示當前時間為uptimeMillis毫秒時發送此消息 */ public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageAtTime(msg, uptimeMillis); }; /** @param delayMillis 這個參數表示延遲多少毫秒之后發送此消息 */ public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageDelayed(msg, delayMillis); }; public final boolean sendMessageDelayed(Message msg, long delayMillis){ if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }; public final boolean sendMessageAtFrontOfQueue(Message msg) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, 0); }; public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis); };
可以看到除了sendMessageAtFrontOfQueue方法,其他方法最終都會產生一個Message對象去調用sendMessageAtTime方法,sendMessageAtTime中獲取當前的消息隊列,然后enqueueMessage方法把新產生的Message對象放入隊列當中。
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
系列目錄: