Handler的異步消息處理運行機制狰住,線程間通信

一、引言

Android開發(fā)中總是免不了處理一些耗時的操作肮蛹,如網(wǎng)絡請求、IO文件讀寫等等酵幕,都需要用子線程來處理缓苛,耗時操作往往也伴隨著更新UI的顯示。此時就涉及到UI線程與子線程之間的通信問題笔刹。為此Android系統(tǒng)引入了Handler異步消息處理的機制冬耿。

二、在子線程中更新UI

Android中想要在子線程中更新UI日月,通常有三種辦法:

  1. Handler的post方法
  2. View視圖控件的post方法
  3. Activity的runOnUiThread()方法

Handler的post方法缤骨,應該都很清楚,內部的Runnable的run方法已經(jīng)是在UI線程執(zhí)行了精拟。View的post方法虱歪、Activity的runOnUiThread()方法怎么也可以在UI線程呢,來看看其內部實現(xiàn):

// View.java
public boolean post(Runnable action) {
    final AttachInfo attachInfo = mAttachInfo;
    if (attachInfo != null) {
        return attachInfo.mHandler.post(action);
    }

    // Postpone the runnable until we know on which thread it needs to run.
    // Assume that the runnable will be successfully placed after attach.
    getRunQueue().post(action);
    return true;
}

// Activity.java
public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }

很顯然從源碼可以看出最終都是交給主線程Handler的post方法來處理师枣。那么為什么主線程聲明實例化的Handler的post方法在子線程調用就可以用來更新UI呢萧落?這個問題暫時先放這里铐尚。接下來進一步分析Handler哆姻。

三、Handler的消息處理機制

在Handler的消息處理架構中矛缨,和Message、MessageQueue灵妨、Looper這三個類是緊密相連的。
Message:消息數(shù)據(jù)承載類货抄,可以是事件任務消息朱转,也可以是其它的實體數(shù)據(jù)消息。
MessageQueue:消息隊列藤为。用于將消息入隊和出隊,以及消息從隊列刪除釋放的管理分别。
Looper:消息循環(huán)處理器存淫。用于維持一個死循環(huán)不斷的從MessageQueue中取出消息,并將消息分發(fā)給設置的目標對象處理(target即Handler)煌往。
Handler:它是整個機制的輔助類轧邪。也是提供給客戶端使用對外暴露Api。用于輔助把消息加入隊列曲管、刪除釋放消息事件和消息的回調處理硕糊。

Handler中我們最常用的有post()、postDelay()檬某、sendMessage()等方法螟蝙,直接或者間接的在內部構建一個Message消息對象然后通過MQ(MessageQueue)的enqueueMessage來處理消息入隊的工作。App啟動的時候在ActivityThread類的main方法里就先通過prepareMainLooper方法預加載了一個Looper對象场斑,然后通過loop方法開啟了消息循環(huán)器。

// ActivityThread.java
public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    ...
    Looper.loop();
    ...
}

以上的Looper對象是主線程的喧半,因此構造的MQ消息隊列也是主線程的青责,loop()方法中不斷循環(huán)取出隊列中的消息,通過handler的dispatchMessage方法分發(fā)消息吴菠。當然從一個事件消息的發(fā)送入隊到出隊處理回調不一定是實時的浩村,MQ的enqueueMessage和next方法可以看出它是一個單向鏈表隊列,入隊的時候根據(jù)消息發(fā)送的時間when按升序排序酿矢,當when為0時插入到隊列頭部怎燥。

Handler異步消息處理運行機制原理圖
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末铐姚,一起剝皮案震驚了整個濱河市隐绵,隨后出現(xiàn)的幾起案子之众,更是在濱河造成了極大的恐慌,老刑警劉巖依许,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棺禾,死亡現(xiàn)場離奇詭異,居然都是意外死亡峭跳,警方通過查閱死者的電腦和手機膘婶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛀醉,“玉大人悬襟,你說我怎么就攤上這事≌螅” “怎么了古胆?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逸绎。 經(jīng)常有香客問我,道長夭谤,這世上最難降的妖魔是什么棺牧? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮朗儒,結果婚禮上颊乘,老公的妹妹穿的比我還像新娘。我一直安慰自己醉锄,他們只是感情好乏悄,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著恳不,像睡著了一般檩小。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上烟勋,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天规求,我揣著相機與錄音,去河邊找鬼卵惦。 笑死阻肿,一個胖子當著我的面吹牛,可吹牛的內容都是我干的沮尿。 我是一名探鬼主播丛塌,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼畜疾!你這毒婦竟也來了赴邻?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤庸疾,失蹤者是張志新(化名)和其女友劉穎乍楚,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體届慈,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡徒溪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了金顿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臊泌。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖揍拆,靈堂內的尸體忽然破棺而出渠概,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布播揪,位于F島的核電站贮喧,受9級特大地震影響,放射性物質發(fā)生泄漏猪狈。R本人自食惡果不足惜箱沦,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雇庙。 院中可真熱鬧谓形,春花似錦、人聲如沸疆前。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽竹椒。三九已至童太,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碾牌,已是汗流浹背康愤。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留舶吗,地道東北人征冷。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像誓琼,于是被迫代替她去往敵國和親检激。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內容