<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ### Android的消息機制 #### 一、取百家所長 附上網友關于本章的總結和歸納 [看云網友同學的總結](http://www.hmoore.net/kancloud/art-of-android-development-reading-notes/90455),[amurocrash同學的總結](http://blog.csdn.net/amurocrash/article/details/48858353),[CSDN網友的歸納](http://blog.csdn.net/qy274770068/article/details/50931898) #### 二、總結歸納 #####1、 Handler的工作過程如圖所示 * * * * * > **Handler的工作過程,圖(page374),我簡單概括一下就是:假設創建Handler的線程是A,耗時操作的線程是B,B線程中拿到handler實例發送消息或者post一個Runnable,實際是調用了MessageQueue的enqueueMessage方法,進入了消息隊列,線程A中的Looper發現了這個消息,就會處理這個消息,也就是消息中的Runnable或者handler的handleMessage方法會被調用,這樣handler中的業務邏輯就被切換到線程A中去了。** * * * * * **如圖** ##### 2、ThreadLocal的工作原理 * * * * * **ThreadLocal我用一句大白話來講解,就是看上去只new了一份,但在每個不同的線程中卻可以擁有不同數據副本的神奇類。其本質是ThreadLocal中的Values類維護了一個Object[],而每個Thread類中有一個ThreadLocal.Values成員,當調用ThreadLocal的set方法時,其實是根據一定規則把這個線程中對應的ThreadLocal值塞進了Values的Object[]數組中的某個index里。這個index總是為ThreadLocal的reference字段所標識的對象的下一個位置。** * * * * * ##### 3、MessageQueue的工作原理 * * * * * **主要方法為enqueueMessage和next。 a. enqueueMessag主要就是一個單鏈表的插入操作, b. next方法是一個無限循環,如果消息隊列中沒有消息,next方法就阻塞,有新消息到來時,next方法會返回這條消息并將其從單鏈表中刪除。** * * * * * ##### 4、Looper的工作原理 * * * * * **a. prepare方法,為當前沒有Looper的線程創建Looper。 b. prepareMainLooper和getMainLooper方法用于創建和獲取ActivityThread的Looper。 c. quit和quitSafely方法,前者立即退出,后者只是設定一個標記,當消息隊列中的所有消息處理完畢后會才安全退出。子線程中創建的Looper建議不需要的時候都要手動終止。 d. loop方法,死循環,阻塞獲取msg并丟給msg.target.dispatchMessage方法去處理,這里的target就是handler。** * * * * * ##### 5、Handler的工作原理: * * * * * **a. 無論sendMessage還是post最終都是調用的sendMessageAtTime方法。 b. 發送消息其實就是把一條消息通過MessageQueue的enqueueMessage方法加入消息隊列,Looper收到消息就會調用handler的dispatchMessage方法。它的處理過程參考書page388的流程圖,一看就懂~ c. 這里我補充一個東西,當我們直接Handler h = new Handler()時,本質調用的是Handler(Callback callback, Boolean async)構造方法,這個方法里會調用Looper.myLooper()方法,這個方法其實就是返回的ThreadLocal里保存的當前線程的Looper,這也就解釋了為什么我們在主線程中這樣new沒有問題,子線程中如果不先Looper.prepare會拋出異常的原因,前面多次說了,因為ActivityThread會在初始化的時候創建自己的Looper。** * * * * *
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看