Android的Message機制(簡單小結)

網上以文檔形式流傳,不知道原文在哪,感謝原作者了!

================簡單調整了下格式就共享了===============================================

對於Android的Message機制主要涉及到三個主要的類,分別是Handler、Message、Looper;首先對每個類做一個簡單介紹;然後再介紹所謂的Android的Message機制是如何實現的,最後給了一個示例。


一、介紹三個相關的類

1、 Handler主要有兩個用途:首先是可以定時處理或者分發消息,其次是可以添加一個執行的行爲在其它線程中執行,

對於Handler中的方法,可以選擇你關心的操作去覆蓋它,處理具體的業務操作,常見的就是對消息的處理可以覆蓋public voidhandleMessage(參數)方法,可以根據參數選擇對此消息是否需要做出處理,這個和具體的參數有關。例如下代碼:

Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {//覆蓋handleMessage方法
    switch (msg.what) {//根據收到的消息的what類型處理
        case BUMP_MSG:
            Log.v("handler", "Handler===="+msg.arg1);//打印收到的消息
            break;
        default:
            super.handleMessage(msg);//這裏最好對不需要或者不關心的消息拋給父類,避免丟失消息
            break;
    }
}
};


2、 消息android.os.Message

android.os.Message是定義一個Messge包含必要的描述和屬性數據,並且此對象可以被髮送給android.os.Handler處理。屬性字段:arg1、arg2、what、obj、replyTo等;其中arg1和arg2是用來存放整型數據的;what是用來保存消息標示的;obj是Object類型的任意對象;replyTo是消息管理器,會關聯到一個handler,handler就是處理其中的消息。通常對Message對象不是直接new出來的,只要調用handler中的obtainMessage方法來直接獲得Message對象。

3、 Looper類主要用於一個線程循環獲取消息隊列中的消息。

Looper的作用主要是負責管理消息隊列,負責消息的出列和入列操作。



二、Android的Message機制是如何實現?

1、爲什麼要使用Message機制主要是爲了保證線程之間操作安全,同時不需要關心具體的消息接收者,使消息本身和線程剝離開,這樣就可以方便的實現定時、異步等操作。

2、Message機制原理示意圖:


Activity   <—————>  EHandler<—–>  Looper<—–>  MessageQueue     

IntentReceiver <—–>  EHandler <—–>  Looper<—–>  MessageQueue       

                                                                                           圖 1


3、 如何實現?(具體描述上圖的消息流的過程)

實現Message機制需要Handler、Message、Looper三個之間的互相作用來實現;當線程A需要發消息給線程B的時候,線程B要用自己的Looper實例化Handler類,就是構造handler對象時,把當前線程的Looper傳給Handler構造函數,handler本身會保存對Looper的引用,handler構造好以後,就可以用handler的obtainMessage方法實例化Message對象,只要把要傳的數據給Handler,Handler就會構造Message對象,並且把Message對象添加到消息隊列裏面。然後就可以調用handler的sendMessage方法把Message對象發送出去,Looper就把消息放到消息隊列中;最後當Looper知道消息隊列不爲空時候,就會循環的從消息隊列中取消息,取出消息就會調用剛纔實例化好的Handler對象的handleMessage方法取處理消息,整個Message過程就是這樣。(如圖1所示)


三、下面介紹一個關於Message機制的簡單的示例,具體的代碼如下:

1、 下面是一個新起的一個線程發消息的示例

handler本身不僅可以發送消息,還可以用post的方式添加一個實現Runnable接口的匿名對象到消息隊列中,在目標收到消息後就可以回調的方式在自己的線程中執行run的方法體,這就是handler兩種典型的使用方式!

class NoLooperThread extends Thread {
    private EventHandler mNoLooperThreadHandler;
    public void run() {
        Looper   myLooper, mainLooper;
        myLooper= Looper.myLooper();   //獲得自己的Looper
            mainLooper= Looper.getMainLooper();    //獲得自己的main的looper
            String obj;
            if (myLooper == null) {
                    mNoLooperThreadHandler = new EventHandler(mainLooper);
                    obj= "NoLooperThread has no looper andhandleMessage function executed in main thread!";
            }else
            {
                    mNoLooperThreadHandler = new EventHandler(myLooper);
                    obj= "This is from NoLooperThread self andhandleMessage function executed in NoLooperThread!";
            }
            mNoLooperThreadHandler.removeMessages(0);    //清空消息隊列
            if (false == postRunnable) {
                    Message m = mNoLooperThreadHandler.obtainMessage(2, 1, 1, obj);    //生成消息對象
                    mNoLooperThreadHandler.sendMessage(m);   //發送消息
                    Log.e(sTag, "NoLooperThread id:" + this.getId());
            }else {
                    mNoLooperThreadHandler.post(new Runnable() {    //添加一個Runnable接口的實現到消息隊列,此Runnable接口的實現不在此                                  線程中執行,會在接收的線程中執行。
                        public void run() {
                            tv.setText("update UI through handler post runnalbe mechanism!");
                            noLooerThread.stop();
                        }
                    });
            }
}


2、下面是一個定時循環發消息的示例,如下代碼:

詳細的解釋參考代碼的註釋

Handler handler = new Handler() {    //創建處理對象handler

                                    publicvoid handleMessage(Message msg) {   

                                                switch (msg.what) {

                                                caseMES: {

                                                            final int N = mCallbacks.beginBroadcast();    //Copy一份回調list,並且標記一個狀態

                                                           for (int i = 0; i <N; i++) {

                                                                       try {

                                                                                    mCallbacks.getBroadcastItem(i).getValue(mMediaPlayer01.getCurrentPosition()); //遍歷所有回調接口                                                                      }catch (Exception e) {

                                                                                    e.printStackTrace();

                                                                         }

                                                            }

                                                            mCallbacks.finishBroadcast();     //完成後狀態復位

                                                            sendMessageDelayed(obtainMessage(MES),1 * 1000);

                                                            }

                                                            break;

                                                            default:

                                                            super.handleMessage(msg);

                                                            }

                                                }

                                    };

  

NOTE:     整個hadleMessage方法相當一個嵌套的循環


四、總結:

所謂的消息機制其實很簡單,實現這種機制需要只需要四步:

     1、實例化Looper(因爲實例化Handler時需要一個looper);

     2、實例化Handler,這裏需要覆蓋handleMessage方法,處理收到的消息;

     3、 實例化Message對象,調用已經實例化好的handler對象的obtainMessage方法,把數據傳給obtainMessage方法,obtainMessage方法就會實例化一個Message對象。(這裏也可以發送實現Runnable接口的對象);

     4、調用Handler的sendMessage方法把實例化好的Message對象發送出去。

對每個線程過程都是一樣的,只要按照上面的四個步驟來就可以發送和接收消息了。


http://blog.csdn.net/dadoneo/article/details/7667726轉載來源

發佈了32 篇原創文章 · 獲贊 30 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章