本文只是表面的帶大家浏覽下Handler,Looper,Message的源碼
Android的消息處理有三個核心類:Looper,Handler和Message。其實還有一個Message Queue(消息隊列),
異步處理大師 Handler:
什麼是handler?handler扮演了往MQ上添加消息和處理消息的角色(只處理由自己發出的消息),即通知MQ它要執行一個任務(sendMessage),並在loop到自己的時候執行該任務(handleMessage),整個過程是異步的。handler創建時會關聯一個looper,默認的構造方法將關聯當前線程的looper,不過這也是可以set的。默認的構造方法:
- public class handler {
-
- final MessageQueue mQueue; // 關聯的MQ
- final Looper mLooper; // 關聯的looper
- final Callback mCallback;
- // 其他屬性
-
- 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());
- }
- }
- // 默認將關聯當前線程的looper
- mLooper = Looper.myLooper();
- // looper不能為空,即該默認的構造方法只能在looper線程中使用
- //UI主線程中默認帶有一個Looper
- if (mLooper == null) {
- throw new RuntimeException(//不能在沒有Looper的線程上創建Handler,
- "Can't create handler inside thread that has not called Looper.prepare()");
- }
- // 重要!!!直接把關聯looper的MQ作為自己的MQ,因此它的消息將發送到關聯looper的MQ上
- mQueue = mLooper.mQueue;
- mCallback = null;
- }
-
- // 其他方法
- }
當然這只是Handler的一個構造方法。Handler本身有四個構造函數,其他其他的三個你可以通過查看源碼來解析,大致雷同。
Handler發送消息
有了handler之後,我們就可以使用 post(Runnabl),sendMessage(Message)
這些方法向MQ上發送消息了。光看這些API你可能會覺得handler能發兩種消息,一種是Runnable對象,一種是message對象,這是直觀的理解,但其實post發出的Runnable對象最後都被封裝成message對象了,見源碼:
Post發送的形式
- public final boolean post(Runnable r){//使用Post發送消息
- return sendMessageDelayed(getPostMessage(r), 0);
- }
- private final Message getPostMessage(Runnable r) {//把一個Runnable包轉成一個Message
- Message m = Message.obtain();
- m.callback = r;
- return m;
- }
- public final boolean sendMessageDelayed(Message msg, long delayMillis){
- if (delayMillis < 0) {
- delayMillis = 0;
- }
- return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
- }
- <pre class="java" name="code"><pre class="java" name="code">public boolean sendMessageAtTime(Message msg, long uptimeMillis){
- boolean sent = false;
- MessageQueue queue = mQueue;
- if (queue != null) {
- /*該handler對象,這確保了looper執行到該message時能找到處理它的handler,直白點就是ABC三個Handler發送消息,最終執行的時候Message消息
- 也是由他們本身來執行,而不會發生A接受到B發送的Message之類的情況*/
- msg.target = this;//
- sent = queue.enqueueMessage(msg, uptimeMillis);//壓入消息隊列
- }else {
- RuntimeException e = new RuntimeException(
- this + " sendMessageAtTime() called with no mQueue");
- Log.w("Looper", e.getMessage(), e);
- }
- return sent;
sendMessage(Message)形式
- public final boolean sendMessage(Message msg){
- return sendMessageDelayed(msg, 0);
- }
- public final boolean sendMessageDelayed(Message msg, long delayMillis){
- if (delayMillis < 0) {
- delayMillis = 0;
- }
- return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
- }
從源碼中我們中我們可以很清晰的看到無論是用psot(Runnable)還是使用sendMessage(Message)方法,最後他們都會調用到同一個方法壓入都一個隊列中去。