HarmonyOS之深入解析线程间的通信
生活随笔
收集整理的這篇文章主要介紹了
HarmonyOS之深入解析线程间的通信
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、概述
① 基本概念
- 在開發(fā)過程中,開經(jīng)常需要在當前線程中處理下載任務等較為耗時的操作,但是又不希望當前的線程受到阻塞。此時,就可以使用 EventHandler 機制。
- EventHandler 是 HarmonyOS 用于處理線程間通信的一種機制,可以通過 EventRunner 創(chuàng)建新線程,將耗時的操作放到新線程上執(zhí)行。這樣既不阻塞原來的線程,任務又可以得到合理的處理。比如:主線程使用 EventHandler 創(chuàng)建子線程,子線程做耗時的下載圖片操作,下載完成后,子線程通過 EventHandler 通知主線程,主線程再更新 UI。
- EventRunner 是一種事件循環(huán)器,循環(huán)處理從該 EventRunner 創(chuàng)建的新線程的事件隊列中獲取 InnerEvent 事件或者 Runnable 任務。InnerEvent 是 EventHandler 投遞的事件。
- EventHandler 是一種用戶在當前線程上投遞 InnerEvent 事件或者 Runnable 任務到異步線程上處理的機制。每一個 EventHandler 和指定的 EventRunner 所創(chuàng)建的新線程綁定,并且該新線程內(nèi)部有一個事件隊列。EventHandler 可以投遞指定的 InnerEvent 事件或 Runnable 任務到這個事件隊列。EventRunner 從事件隊列里循環(huán)地取出事件,如果取出的事件是 InnerEvent 事件,將在 EventRunner 所在線程執(zhí)行 processEvent 回調(diào);如果取出的事件是 Runnable 任務,將在 EventRunner 所在線程執(zhí)行 Runnable 的 run 回調(diào)。
- 一般,EventHandler 有兩個主要作用:
-
- 在不同線程間分發(fā)和處理 InnerEvent 事件或 Runnable 任務。
-
- 延遲處理 InnerEvent 事件或 Runnable 任務。
② 運作機制
- EventHandler 的運作機制如下圖所示:
- 使用 EventHandler 實現(xiàn)線程間通信的主要流程:
-
- EventHandler 投遞具體的 InnerEvent 事件或者 Runnable 任務到 EventRunner 所創(chuàng)建的線程的事件隊列。
-
- EventRunner 循環(huán)從事件隊列中獲取 InnerEvent 事件或者 Runnable 任務。
-
- 處理事件或任務:
-
-
- 如果 EventRunner 取出的事件為 InnerEvent 事件,則觸發(fā) EventHandler 的回調(diào)方法并觸發(fā) EventHandler 的處理方法,在新線程上處理該事件。
-
-
-
- 如果 EventRunner 取出的事件為 Runnable 任務,則 EventRunner 直接在新線程上處理 Runnable 任務。
-
③ 約束和限制
- 在進行線程間通信的時候,EventHandler 只能和 EventRunner 所創(chuàng)建的線程進行綁定, EventRunner 創(chuàng)建時需要判斷是否創(chuàng)建成功,只有確保獲取的 EventRunner 實例非空時,才可以使用 EventHandler 綁定 EventRunner。
- 一個 EventHandler 只能同時與一個 EventRunner 綁定,一個 EventRunner 可以同時綁定多個 EventHandler。
二、應用場景
① EventHandler 開發(fā)場景
- EventHandler 的主要功能是將 InnerEvent 事件或者 Runnable 任務投遞到其他的線程進行處理,其使用的場景包括:
-
- 開發(fā)者需要將 InnerEvent 事件投遞到新的線程,按照優(yōu)先級和延時進行處理。投遞時,EventHandler 的優(yōu)先級可在 IMMEDIATE、HIGH、LOW、IDLE 中選擇,并設置合適的 delayTime。
-
- 開發(fā)者需要將 Runnable 任務投遞到新的線程,并按照優(yōu)先級和延時進行處理。投遞時,EventHandler 的優(yōu)先級可在 IMMEDIATE、HIGH、LOW、IDLE 中選擇,并設置合適的 delayTime。
-
- 需要在新創(chuàng)建的線程里投遞事件到原線程進行處理。
② EventRunner 工作模式
- EventRunner 的工作模式可以分為托管模式和手動模式。兩種模式是在調(diào)用 EventRunner 的 create() 方法時,通過選擇不同的參數(shù)來實現(xiàn)的,默認為托管模式。
-
- 托管模式:不需要調(diào)用 run() 和 stop() 方法去啟動和停止 EventRunner。當 EventRunner 實例化時,系統(tǒng)調(diào)用 run() 來啟動 EventRunner;當 EventRunner 不被引用時,系統(tǒng)調(diào)用 stop() 來停止 EventRunner。
-
- 手動模式:需要自行調(diào)用 EventRunner 的 run() 方法和 stop() 方法來確保線程的啟動和停止。
三、API 說明
① EventHandler
- EventHandler 的屬性 Priority(優(yōu)先級):EventRunner 將根據(jù)優(yōu)先級的高低從事件隊列中獲取事件或者 Runnable 任務進行處理。
- EventHandler 的屬性:
| Priority.IMMEDIATE | 表示事件被立即投遞 |
| Priority.HIGH | 表示事件先于LOW優(yōu)先級投遞 |
| Priority.LOW | 表示事件優(yōu)于IDLE優(yōu)先級投遞,事件的默認優(yōu)先級是LOW |
| Priority.IDLE | 表示在沒有其他事件的情況下,才投遞該事件 |
- EventHandler 的主要接口:
| EventHandler(EventRunner runner) | 利用已有的EventRunner來創(chuàng)建EventHandler |
| current() | 在processEvent回調(diào)中,獲取當前的EventHandler |
| processEvent?(InnerEvent event) | 回調(diào)處理事件,由開發(fā)者實現(xiàn) |
| sendEvent?(InnerEvent event) | 發(fā)送一個事件到事件隊列,延時為0ms, 優(yōu)先級為LOW |
| sendEvent?(InnerEvent event, long delayTime) | 發(fā)送一個延時事件到事件隊列,優(yōu)先級為LOW |
| sendEvent?(InnerEvent event, long delayTime, EventHandler.Priority priority) | 發(fā)送一個指定優(yōu)先級的延時事件到事件隊列 |
| sendEvent?(InnerEvent event, EventHandler.Priority priority) | 發(fā)送一個指定優(yōu)先級的事件到事件隊列,延時為0ms |
| sendSyncEvent?(InnerEvent event) | 發(fā)送一個同步事件到事件隊列,延時為0ms,優(yōu)先級為LOW |
| sendSyncEvent?(InnerEvent event, EventHandler.Priority priority) | 發(fā)送一個指定優(yōu)先級的同步事件到事件隊列,延時為0ms,優(yōu)先級不可以是IDLE |
| postSyncTask?(Runnable task) | 發(fā)送一個Runnable同步任務到事件隊列,延時為0ms, 優(yōu)先級為LOW |
| postSyncTask?(Runnable task, EventHandler.Priority priority) | 發(fā)送一個指定優(yōu)先級的Runnable同步任務到事件隊列,延時為0ms |
| postTask?(Runnable task) | 發(fā)送一個Runnable任務到事件隊列,延時為0ms,優(yōu)先級為LOW |
| postTask?(Runnable task, long delayTime) | 發(fā)送一個Runnable延時任務到事件隊列,優(yōu)先級為LOW |
| postTask?(Runnable task, long delayTime, EventHandler.Priority priority) | 發(fā)送一個指定優(yōu)先級的Runnable延時任務到事件隊列 |
| postTask?(Runnable task, EventHandler.Priority priority) | 發(fā)送一個指定優(yōu)先級的Runnable任務到事件隊列,延時為0ms |
| sendTimingEvent(InnerEvent event, long taskTime) | 發(fā)送一個定時事件到隊列,在taskTime時間執(zhí)行,如果taskTime小于當前時間,立即執(zhí)行,優(yōu)先級為LOW |
| sendTimingEvent(InnerEvent event, long taskTime, EventHandler.Priority priority) | 發(fā)送一個帶優(yōu)先級的事件到隊列,在taskTime時間執(zhí)行,如果taskTime小于當前時間,立即執(zhí)行 |
| postTimingTask(Runnable task, long taskTime) | 發(fā)送一個Runnable任務到隊列,在taskTime時間執(zhí)行,如果taskTime小于當前時間,立即執(zhí)行,優(yōu)先級為LOW |
| postTimingTask(Runnable task, long taskTime, EventHandler.Priority priority) | 發(fā)送一個帶優(yōu)先級的Runnable任務到隊列,在taskTime時間執(zhí)行,如果taskTime小于當前時間,立即執(zhí)行 |
| removeEvent(int eventId) | 刪除指定id的事件 |
| removeEvent(int eventId, long param) | 刪除指定id和param的事件 |
| removeEvent(int eventId, long param, Object object) | 刪除指定id、param和object的事件 |
| removeAllEvent() | 刪除該EventHandler的所有事件 |
| getEventName(InnerEvent event) | 獲取事件的名字 |
| getEventRunner() | 獲取該EventHandler綁定的EventRunner |
| isIdle() | 判斷隊列是否為空 |
| hasInnerEvent(Runnable runnable) | 根據(jù)指定的runnable參數(shù),檢查是否有還未被處理的任務。可以根據(jù)不同的入?yún)⑦M行檢查,詳見EventHandler |
② EventRunner
- EventRunner 主要接口:
| create?() | 創(chuàng)建一個擁有新線程的EventRunner |
| create?(boolean inNewThread) | 創(chuàng)建一個擁有新線程的EventRunner,inNewThread為true時,EventRunner為托管模式,系統(tǒng)將自動管理該EventRunner;inNewThread為false時,EventRunner為手動模式 |
| create?(String newThreadName) | 創(chuàng)建一個擁有新線程的EventRunner, 新線程的名字是 newThreadName |
| current?() | 獲取當前線程的EventRunner |
| run?() | EventRunner為手動模式時,調(diào)用該方法啟動新的線程 |
| stop?() | EventRunner為手動模式時,調(diào)用該方法停止新的線程 |
③ InnerEvent
- InnerEvent 的屬性:
| eventId | 事件的ID, 由開發(fā)者定義用來辨別事件 |
| object | 事件攜帶的Object信息 |
| param | 事件攜帶的long型數(shù)據(jù) |
- InnerEvent 的接口:
| drop?() | 釋放一個事件實例 |
| get?() | 獲得一個事件實例 |
| get?(int eventId) | 獲得一個指定的eventId的事件實例 |
| get?(int eventId, long param) | 獲得一個指定的eventId和param的事件實例 |
| get?(int eventId, long param, Object object) | 獲得一個指定的eventId,param和object的事件實例 |
| get?(int eventId, Object object) | 獲得一個指定的eventId和object的事件實例 |
| PacMap getPacMap() | 獲取PacMap,如果沒有,會新建一個 |
| Runnable getTask() | 獲取Runnable任務 |
| PacMap peekPacMap() | 獲取PacMap |
| void setPacMap(PacMap pacMap) | 設置PacMap |
四、線程的通信使用
① EventHandler 投遞 InnerEvent 事件
- EventHandler 投遞 InnerEvent 事件,并按照優(yōu)先級和延時進行處理。
- 創(chuàng)建 EventHandler 的子類,在子類中重寫實現(xiàn)方法 processEvent() 來處理事件:
- 創(chuàng)建 EventRunner,以手動模式為例:
- 創(chuàng)建 EventHandler 子類的實例:
- 獲取 InnerEvent 事件:
- 投遞事件,投遞的優(yōu)先級以 IMMEDIATE 為例,延時選擇 0ms 和 2m:
- 啟動和停止 EventRunner,如果為托管模式,則不需要此步驟:
② EventHandler 投遞 Runnable 任務
- EventHandler 投遞 Runnable 任務,并按照優(yōu)先級和延時進行處理。
- 創(chuàng)建 EventHandler 的子類,創(chuàng)建 EventRunner,并創(chuàng)建 EventHandler 子類的實例,步驟與 EventHandler 投遞 InnerEvent 場景的前三個步驟相同。
- 創(chuàng)建 Runnable 任務。
- 投遞 Runnable 任務,投遞的優(yōu)先級以 IMMEDIATE 為例,延時選擇 0ms 和 2ms。
- 啟動和停止 EventRunner,如果是托管模式,則不需要此步驟:
③ 在新創(chuàng)建的線程里投遞事件到原線程
- EventHandler 從新創(chuàng)建的線程投遞事件到原線程并進行處理。
- 創(chuàng)建 EventHandler 的子類,在子類中重寫實現(xiàn)方法 processEvent() 來處理事件。
- 創(chuàng)建 EventRunner,以手動模式為例:
- 創(chuàng)建 EventHandler 子類的實例:
- 獲取 InnerEvent 事件:
- 投遞事件,在新線程上直接處理:
- 啟動和停止 EventRunner,如果是托管模式,則不需要此步驟:
五、完整示例
- 非托管情況:
- 托管情況:
總結(jié)
以上是生活随笔為你收集整理的HarmonyOS之深入解析线程间的通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HarmonyOS之深入解析线程管理
- 下一篇: iOS之深入解析CFRunloop的多线