Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android消息循環分析

Android消息循環分析

編輯:關於Android編程

我們的常用的系統中,程序的工作通常是有事件驅動和消息驅動兩種方式,在Android系統中,Java應用程序是靠消息驅動來工作的。

消息驅動的原理就是:
1. 有一個消息隊列,可以往這個隊列中投遞消息;
2. 有一個消息循環,不斷從消息隊列中取出消息,然後進行處理。
在Android中通過Looper來封裝消息循環,同時在其中封裝了一個消息隊列MessageQueue。
另外Android給我們提供了一個封裝類,來執行消息的投遞,消息的處理,即Handler。

在我們的線程中實現消息循環時,需要創建Looper,如:

class LooperThread extends Thread {
    public Handler mHandler;
    public void run() {
        Looper.prepare(); //1.調用prepare
        ......
        Looper.loop();    //2.進入消息循環
    }
}

看上面的代碼,其實就是先准備Looper,然後進入消息循環。
1. 在prepare的時候,創建一個Looper,同時在Looper的構造方法中創建一個消息隊列MessageQueue,同時將Looper保存到TLV中(這個是關於ThreadLocal的,不太懂,以後研究了再說)
2. 調用loop進入消息循環,此處其實就是不斷到MessageQueue中取消息Message,進行處理。

然後再看我們如何借助Handler來發消息到隊列和處理消息

Handler的成員(非全部):

final MessageQueue mQueue;    
final Looper mLooper;    
final Callback mCallback;

Message的成員(非全部):

Handler target;            
Runnable callback;

可以看到Handler的成員包含Looper,通過查看源代碼,我們可以發現這個Looper是有兩種方式獲得的,1是在構造函數傳進來,2是使用當前線程的Looper(如果當前線程無Looper,則會報錯。我們在Activity中創建Handler不需要傳Handler是因為Activity本身已經有一個Looper了),MessageQueue也就是Looper中的消息隊列。

然後我們看怎麼向消息隊列發送消息,Handler有很多方法發送隊列(這個自己可以去查),比如我們看sendMessageDelayed(Message msg, long delayMillis)

public final boolean sendMessageDelayed(Message msg, long delayMillis) {
    if (delayMillis < 0) {    
        delayMillis = 0;    
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);      
// SystemClock.uptimeMillis() 獲取開機到現在的時間    
} 
    //最終所有的消息是通過這個發,uptimeMillis是絕對時間(從開機那一秒算起)
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {    
    boolean sent = false;    
    MessageQueue queue = mQueue;    
    if (queue != null) {    
        msg.target = this;    
        sent = queue.enqueueMessage(msg, uptimeMillis);    
    }   
    return sent;   
}

看上面的的代碼,可以看到Handler將自己設為Message的target,然後然後將msg放到隊列中,並且指定執行時間。

消息處理

處理消息,即Looper從MessageQueue中取出隊列後,調用msg.target的dispatchMessage方法進行處理,此時會按照消息處理的優先級來處理:
1. 若msg本身有callback,則交其處理;
2. 若Handler有全局callback,則交由其處理;
3. 以上兩種都沒有,則交給Handler子類實現的handleMessage處理,此時需要重載handleMessage。

我們通常采用第三種方式進行處理。

注意!!!!我們一般是采用多線程,當創建Handler時,LooperThread中可能還未完成Looper的創建,此時,Handler中無Looper,操作會報錯。

我們可以采用Android為我們提供的HandlerThread來解決,該類已經創建了Looper,並且通過wait/notifyAll來避免錯誤的發生,減少我們重復造車的事情。我們創建該對象後,調用getLooper()即可獲得Looper(Looper未創建時會等待)。

補充

本文所屬為Android中java層的消息循環機制,其在Native層還有消息循環,有單獨的Looper。並且2.3以後MessageQueue的核心向Native層下移,native層java層均可以使用。這個我沒有過多的研究了!哈哈

PS:本文參考《深入理解Android:卷I》

原文地址:http://blog.isming.me/blog/2014/04/02/android-message-loop-analyze/ ,轉載請注明出處。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved