同一線程內多Handler使用淺析

轉載自:https://blog.csdn.net/u011573355/article/details/50735604

做android開發的人都知道Handler處理機制,handler的出現就是爲了保證UI線程安全,對UI的修改只有UI線程可以操作,不允許其他線程操作,下面對Handler異步消息處理機制再做一下簡單的介紹:
1、成員介紹
Message:主要功能是進行消息的封裝,同時可以指定消息的操作形式;
Looper:消息循環泵,用來爲一個線程跑一個消息循環。每一個線程最多只可以擁有一個。
MessageQueue:就是一個消息隊列,存放消息的地方。每一個線程最多只可以擁有一個。
Handler:消息的處理者,handler 負責將需要傳遞的信息封裝成Message,發送給Looper,繼而由Looper將Message放入MessageQueue中。當Looper對象看到MessageQueue中含有Message,就將其廣播出去。該handler 對象收到該消息後,調用相應的handler 對象的handleMessage()方法對其進行處理。
2、同線程各成員的關係及數量
①一個線程中只能有一個Looper,只能有一個MessageQueue,可以有多個Handler,多個Messge;
②一個Looper只能維護唯一一個MessageQueue,可以接受多個Handler發來的消息;
③一個Message只能屬於唯一一個Handler;
④同一個Handler只能處理自己發送給Looper的那些Message;

理清各成員之間的關係就好辦了,網上好多都是在其他線程中Handler講解,下面我來簡單說一下在同一線程中,多個handler的用法,有的人可能會說,同一個線程爲啥還要多個Handler,其實就是爲了相互獨立,互不干擾,各自處理各自的消息,比如說Handler1收到一個點擊消息,它想將消息隊列裏面的所有點擊消息,那它可以通過removeMessages(int what) 方法清除,這時如果handler2如果也有點擊消息,就不會受到影響,因爲誰發的Message,誰處理。
舉個例子:
第一個Handler:

Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);

            switch (msg.what) {
            case LOOP_DISPLAY:              
                mHandler.sendEmptyMessageDelayed(LOOP_DISPLAY, 2000);               
                break;
            case MANUAL:
                mHandler.removeMessages(LOOP_DISPLAY);
                break;
            default:
                break;
            }
        }

    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

第二個Handler 在另外一個類中

Handler mHandler1 = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);

            switch (msg.what) {
            case LOOP_DISPLAY:              
                mHandler1.sendEmptyMessageDelayed(LOOP_DISPLAY, 2000);              
                break;
            case MANUAL:                
                break;
            default:
                break;
            }
        }

    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

這兩個類中的handler在同一個線程中,因此會共用同一個looper和同一個MessageQueue,但是當第一個handler調用mHandler.removeMessages(LOOP_DISPLAY);只是讓mHandler停止接收LOOP_DISPLAY消息,而mHandler1的LOOP_DISPLAY消息如果存在會繼續接收,兩者互不干擾,這是由於消息隊列中的每一個Message都會綁定它自己的handler,只有自己的發送該消息的handler才能處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章