<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ### **概述** Android應用程序與傳統的PC應用程序一樣,都是消息驅動的。也就是說,在Android應用程序主線程中,所有函數都是在一個消息循環中執行的。Android應用程序其它線程,也可以像主線程一樣,擁有消息循環。Android應用程序主線程是一個特殊的線程,因為它同時也是UI線程以及觸摸屏、鍵盤等輸入事件處理線程。主線程對消息循環很敏感,一旦發生阻塞,就會影響UI的流暢度,甚至發生ANR問題。 主要講Android應用程序線程消息循環原理,主要涉及到Handler和Looper兩個類,以及根據消息循環的不同使用場景,總結出三種線程使用模型。掌握Android應用程序消息處理機制,有助于我們熟練地使用同步和異步編程,提高程序的運行性能。 * 線程與消息的關系 * 線程的消息隊列創建 * 線程的消息循環 * 線程的消息發送 * 線程的消息處理 * 消息在異步任務的應用 #### **線程與消息的關系** **Android應用程序有兩種類型的線程** * 帶有消息隊列,用來執行循環性任務 * 有消息時就處理 * 沒有消息時就睡眠 * 例子:主線程、android.os.HandlerThread * 沒有消息隊列,用來執行一次性任務 * 任務一旦執行完成便退出 * 例子:java.lang.Thread **帶有消息隊列的線程四要素** * Message(消息) * MessageQueue(消息隊列) * Looper(消息循環) * Handler(消息發送和處理) **Message、 MessageQueue、 Looper和Handler的交互過程** ![](https://box.kancloud.cn/7dda2bebc9eaa4cde5c2fdfbeb96db49_546x357.png) #### **線程的消息隊列創建** **MessageQueue與Looper的關系** ![](https://box.kancloud.cn/95f870bb4606176a77c0938995e204f6_570x396.jpg) **例1:ServerThread** ![](https://box.kancloud.cn/7342d06e988dc673e3ee0a2502f1eeeb_615x531.png) **例2:ActivityThread** ![](https://box.kancloud.cn/754b52ab968f4ebb332f41d3b9889497_684x273.png) **Looper.prepare/prepareMainLooper** ![](https://box.kancloud.cn/bbcce720b5b5ea8526143f34f0f4884c_678x560.png) **new Looper – 創建Java層的Looper** ![](https://box.kancloud.cn/4f22905a83a0bb2618ea558bbf4e2615_465x178.png) **new MessageQueue** ![](https://box.kancloud.cn/15ea9d10a2bc49b18cb93d2854d9df84_436x343.png) **nativeInit** ![](https://box.kancloud.cn/14d740ea5553e3fec753a9368a6b8545_798x257.png) **new NativeMessageQueue** ![](https://box.kancloud.cn/f6bacc1c76082b6a39b66ea35caff497_770x122.png) **new Looper – 創建C++層的Looper** ![](https://box.kancloud.cn/fb26f3abc74bee75b69bbd3445b88193_868x377.png) **pipe** * 一種進程/線程間通信機制 * 包含一個寫端文件描述符和一個讀端文件描述符 * Looper通過讀端文件描述符等待新消息的到來 * Handler通過寫端文件描述符通知Looper新消息的到來 ![](https://box.kancloud.cn/5342d2719cf0b10ceeb177f73d1a0677_557x188.png) **epoll** * 一種I/O多路復用技術,select/poll加強版 * epoll_create:創建一個epoll句柄 * epoll_ctl:設置要監控的文件描述符 * epoll_wait:等待監控的文件描述符發生IO事件 * Looper利用epoll來監控消息隊列是否有新的消息,也就是監控消息管道的讀端文件描述符 **為什么要用epoll** Looper除了監控消息管道之外,還需要監控其它文件描述符,例如,用來接收鍵盤/觸摸屏事件的文件描述符 #### **線程的消息循環** **例1:ServerThread** ![](https://box.kancloud.cn/7342d06e988dc673e3ee0a2502f1eeeb_615x531.png) **例2:ActivityThread** ![](https://box.kancloud.cn/754b52ab968f4ebb332f41d3b9889497_684x273.png) **Looper.loop – Java層的Looper** ![](https://box.kancloud.cn/c1c859edcda16d86b18abddd2234e5cb_694x480.png) **MessageQueue.next** ![](https://box.kancloud.cn/bb2bc78ebfbb1c3bf08f2a8481966f14_700x581.png) **nativePollOnce** ![](https://box.kancloud.cn/17e37c77f5d995c04a21396928e0eec4_721x83.png) **NativeMessageQueue.pollOnce** ![](https://box.kancloud.cn/695de9b609e935fd04ca338b8b2ee60c_559x93.png) **Looper.pollOnce – C++層的Looper** ![](https://box.kancloud.cn/841eb954c6e41f17775ed2fb80a9696f_779x360.png) **Looper.pollInner** ![](https://box.kancloud.cn/f3222f5cc7e3f1a06a4989898468f435_636x589.png) **Looper.awoken** ![](https://box.kancloud.cn/48c830fdf93c1c1ab7f53044372ab87b_667x157.png) #### **線程的消息發送** **常用的消息發送接口** * Handler.sendMessage 帶一個Message參數,用來描述消息的內容 * Handler.post 帶一個Runnable參數,會被轉換為一個Message參數 **Message** ![](https://box.kancloud.cn/7938691aa1f1ae3ba78af8f3dd61c0f8_468x430.png) **Handler.sendMessage/post** ![](https://box.kancloud.cn/7399f96f0b7d8e24992a681481ac5302_524x395.png) **Handler.sendMessageDelayed** ![](https://box.kancloud.cn/8c461c0b1eae53363152e51f821e46d8_736x226.png) **Handler.sendMessageAtTime** ![](https://box.kancloud.cn/a729811d4ae643e874cf2561b4ae78e4_670x274.png) **Handler.enqueueMessage** ![](https://box.kancloud.cn/bcbdcb65bd8358a8614b0d4eb01d0450_809x225.png) **MessageQueue.enqueueMessage** ![](https://box.kancloud.cn/1edfff6915efae821dd2b71355942afe_585x589.png) **備注**: mBlocked:Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout. **nativeWake** ![](https://box.kancloud.cn/3875a6dd4f5499405e06c4537ffd931f_812x75.png) **NativeMessageQueue.wake** ![](https://box.kancloud.cn/e639027cc8f484306601d876bfc77afa_323x60.png) **Looper.wake** ![](https://box.kancloud.cn/c81efd87976c9776c5513cb3ad715651_609x242.png) **回顧消息循環過程** ![](https://box.kancloud.cn/454a5dbd4b6e3f74ca6eda72648324f4_731x391.jpg) **Handler.dispatchMessage** ![](https://box.kancloud.cn/dd49e39c634e90f2df7cd9226ca7c8b8_544x545.png) #### **消息在異步任務的應用** **在主線程為什么要用異步任務?** * 主線程任務繁重 * 執行組件生命周期函數 * 執行業務邏輯 * 執行用戶交互 * 執行UI渲染 * 主線程處理某一個消息時間過長時會產生ANR * Service生命周期函數 – 20s * Broadcast Receiver接收前臺優先級廣播函數 –10s * Broadcast Receiver接收后臺優先級廣播函數 – 60s * 影響輸入事件處理的函數 – 5s * 影響進程啟動的函數 – 10s * 影響Activity切換的函數– 2s **備注**: 一個進程如果正在接收一個前臺優先級廣播,那么它所在的進程調度組就為Process.THREAD_GROUP_DEFAULT ,如果是正在接收后臺優先級廣播,那么它所在的進程調度組就為Process.THREAD_GROUP_BG_NONINTERACTIVE。發送廣播時,通過Intent.FLAG_RECEIVER_FOREGROUND標志來指定是前臺優先級還是后臺優先級 **基于消息的異步任務接口** * android.os.HandlerThread 適合用來處于不需要更新UI的后臺任務 * android.os.AyncTask 適合用來處于需要更新UI的后臺任務 **android.os.HandlerThread** ![](https://box.kancloud.cn/737497aff95db032cf420f8dd6881be5_408x446.png) **啟動HandlerThread** ~~~ HandlerThread handlerThread = new HandlerThread("Handler Thread"); handlerThread.start(); ~~~ **向HandlerThread分配任務** ![](https://box.kancloud.cn/53849acb24072f6965c46a242537bd06_429x226.png) ~~~ ThreadTask threadTask = new ThreadTask(); Handler handler = new Handler(handlerThread.getLooper()); handler.post(threadTask); ~~~ **退出HandlerThread** ~~~ handlerThread.quit(); ~~~ ![](https://box.kancloud.cn/43259826815f83fa6abb3c248919e877_551x565.png) **android.os.AyncTask** * 在進程內維護一個線程池來執行任務 * 任務在開始執行、執行過程以及結束執行時均可以與主線程進行交互 * 任務是通過一個Handler向主線程發送消息以達到交互的目的 **例子** ![](https://box.kancloud.cn/69d42672979ebfb66efb9278eb92cea1_692x576.png) **AysnTask的相關成員變量定義** ![](https://box.kancloud.cn/996ace050c8acf2bf74512a7adb12e92_763x465.png) **用來向主線程發送消息的InternalHandler** ![](https://box.kancloud.cn/70514de799f8bba23e0c0c6df2954ed3_581x404.png) **任務執行過程或者結果數據--AsyncTaskResult** ![](https://box.kancloud.cn/99d8101799cc2b0530216b78c853c71c_490x246.png) **創建任務** ![](https://box.kancloud.cn/03196c1ed0d95a86c923e6595c2d2332_714x578.png) **執行任務** ![](https://box.kancloud.cn/1454718f30ea25a390b919b23afc1630_653x231.png) ![](https://box.kancloud.cn/ca7d4b763610502137514fdd97e4852d_681x508.jpg) **觸發AsyncTask.doInBackground在工作線程中被調用** **更新任務進度** ![](https://box.kancloud.cn/acc0f1f17dab5133528bb3f93054cbb9_625x160.jpg) ![](https://box.kancloud.cn/d7a79190e26e571192c07133c3bfdcc6_651x409.jpg) **MESSAGE_POST_PROGRESS通過sHandler發送到主線程的消息隊列** **觸發AsyncTask.onProgressUpdate在主線程中被** **任務結束時,MESSAGE_POST_RESULT通過sHandler發送到主線程的消息隊列,觸發AsyncTask.finish在主線程中被調用** ![](https://box.kancloud.cn/61b2ad372eb4f871bb52bc36630d6d65_482x176.png) ![](https://box.kancloud.cn/aabaed00cb052ee3b38dd40eb7b97bc5_679x487.jpg) ![](https://box.kancloud.cn/dcddd565ec263b06024d5b64e1b3a8e5_657x410.jpg) **進一步觸發AsyncTask.onPostExecute在主線程中被調用** **任務中途取消時,MESSAGE_POST_CANCEL通過sHandler發送到主線程的消息隊列,觸發AsyncTask.onCancel在主線程中被調用** ![](https://box.kancloud.cn/4dd0c6ad9e541028fd9d97d6c18c2c4f_504x131.png) ![](https://box.kancloud.cn/182ea492e0898d3e823cf69333403000_691x514.jpg) ![](https://box.kancloud.cn/f48e612e75149ecf3241aabc21613826_668x418.jpg)
                  <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>

                              哎呀哎呀视频在线观看