Handler 消息機制及系統(tǒng)層應(yīng)用

消息機制

Android 消息機制是 Android 系統(tǒng)運行的基礎(chǔ)伤柄,主要涉及到 Looper、MessageQueue、Handler 等類茁影。

  • Looper

    1. Looper 是消息循環(huán)的根據(jù)地;
    2. 它在 prepare 方法中利用 ThreadLocal 將 Looper 與當(dāng)前線程進行綁定丧凤,Handler 初始化時會對當(dāng)前線程進行判斷募闲,如果不是 Looper 線程,那就會拋出異常愿待;
    3. 一個 Looper 與一個 MessageQueue 進行唯一綁定浩螺,消息循環(huán)實際上是由 MessageQueue 實現(xiàn)的:無限循環(huán)調(diào)用 MessageQueue 的 next 方法,如果有消息就通過 Handler#target 屬性回調(diào)處理仍侥,如果沒有就阻塞(真正的阻塞也在 next 方法里)要出;
  • MessageQueue

    Message 的存儲容器,以 Message.when 進行排序农渊。名為消息隊列患蹂,實際數(shù)據(jù)結(jié)構(gòu)為鏈表,因為鏈表在插入和讀取上有較大優(yōu)勢砸紊,而頻繁插入讀取正是消息機制的應(yīng)用場景传于。

  • Handler

    1. 在構(gòu)造方法中校驗當(dāng)前線程是否為 Looper 線程;可顯示指定 Looper 對象醉顽,指定的 Looper 對象即為消息處理的目標線程沼溜;

    2. 內(nèi)部的 MessageQueue 對象實際上來自于 Looper 持有的引用,調(diào)用 enqueueMessage 方法將消息入隊時游添,會通過 target 屬性將當(dāng)前 Handler 與當(dāng)前 Message 綁定系草,方便之后處理具體的消息時,能夠讓某個消息找到目標 Handler 對象唆涝;(同一線程可以有多個 Handler找都,不同 Handler 發(fā)送的消息可以被發(fā)送它們的 Handler 正確處理)

    3. 最后處理 Message 時是在 Looper 中調(diào)用 dispatchMessage 方法:

      public void dispatchMessage(Message msg) {
          if (msg.callback != null) {
            handleCallback(msg);
          } else {
            if (mCallback != null) {
              if (mCallback.handleMessage(msg)) {
                return;
              }
            }
            handleMessage(msg);
          }
      }
      

      由上面的代碼也可以看出優(yōu)先級:

      1. 如果有 callback,那就不會執(zhí)行 handleMessage 方法石抡;
      2. 如果是在聲明 Handler 時檐嚣,從構(gòu)造器傳入了 Callback 對象,并且該方法返回 true,那就不會再回調(diào) handleMessage 方法嚎京;如果返回了 false嗡贺,那就會繼續(xù)回調(diào)到 handleMessage 方法;

系統(tǒng)層對 Handler 的應(yīng)用

介紹完消息機制的基本概念和原理后鞍帝,下面說一下系統(tǒng)級別對 Handler 機制的應(yīng)用诫睬。

我們知道 App 的啟動入口在 ActivityThread 的 main 方法中。

  1. 當(dāng)這個方法執(zhí)行時帕涌,會調(diào)用 Looper.prepareMainLooper() 方法摄凡,從而將當(dāng)前線程轉(zhuǎn)換為唯一的 UI 線程并構(gòu)建 ActivityThread 實例;
  2. 之后調(diào)用 attach 方法蚓曼,在這個方法中會創(chuàng)建 Binder 通道亲澡,獲取到 AMS 對象,與 system_server 建立連接纫版;
  3. 開啟 Looper 循環(huán)床绪;

在與 system_server 建立連接后,ActivityThread 與 ActivityManagerService 進行通信其弊,ActivityThread 以 IActivityManager 為媒介操作 AMS癞己,AMS 以 IApplicationThread 為媒介操作 ActivityThread,在 Binder 線程與 UI 線程之間進行交互梭伐。

在 attach 方法執(zhí)行過程中痹雅,AMS 最終會回調(diào)到 ApplicationThread 的 bindApplication 方法中:

public final void bindApplication(){
  sendMessage(H.BIND_APPLICATION, data);
}

緊接著,UI 線程會使用之前聲明 Handler 對象 mH糊识,開啟系統(tǒng)層的 Handler 消息處理的旅途绩社。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市技掏,隨后出現(xiàn)的幾起案子铃将,更是在濱河造成了極大的恐慌项鬼,老刑警劉巖哑梳,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異绘盟,居然都是意外死亡鸠真,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門龄毡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吠卷,“玉大人,你說我怎么就攤上這事沦零〖栏簦” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵路操,是天一觀的道長疾渴。 經(jīng)常有香客問我千贯,道長,這世上最難降的妖魔是什么搞坝? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任搔谴,我火速辦了婚禮,結(jié)果婚禮上桩撮,老公的妹妹穿的比我還像新娘敦第。我一直安慰自己,他們只是感情好店量,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布芜果。 她就那樣靜靜地躺著,像睡著了一般融师。 火紅的嫁衣襯著肌膚如雪师幕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天诬滩,我揣著相機與錄音霹粥,去河邊找鬼。 笑死疼鸟,一個胖子當(dāng)著我的面吹牛后控,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播空镜,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼浩淘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吴攒?” 一聲冷哼從身側(cè)響起张抄,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎洼怔,沒想到半個月后署惯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡镣隶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年极谊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片安岂。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡轻猖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出域那,到底是詐尸還是另有隱情咙边,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站败许,受9級特大地震影響友瘤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜檐束,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一辫秧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧被丧,春花似錦盟戏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至黄选,卻和暖如春蝇摸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背办陷。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工貌夕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人民镜。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓啡专,卻偏偏與公主長得像,于是被迫代替她去往敵國和親制圈。 傳聞我的和親對象是個殘疾皇子们童,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容