OpenHarmony 源碼解析之分布式任務調(diào)度(一)
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
前言
鴻蒙系統(tǒng)(HarmonyOS)支持在本地程序里調(diào)起遠程任務,這個功能是更底層的分布式任務調(diào)度子系統(tǒng)支撐的,并且已經(jīng)貢獻到開源鴻蒙(OpenHarmony)代碼里。為了更全面地理解與掌握分布式任務調(diào)度子系統(tǒng),我先從分布式遠程啟動這個簡單的功能開始,利用開源鴻蒙開放的源代碼,進行深入學習。
以下行文如無特別說明,所述說的鴻蒙系統(tǒng)均指開源鴻蒙系統(tǒng)(OpenHarmony 3.0 LTS版本)。

OpenHarmony 架構(gòu)圖
概述
先從開源鴻蒙文檔入手:
分布式任務調(diào)度模塊,通過主從設(shè)備服務代理機制,在OpenHarmony操作系統(tǒng)上建立起分布式服務平臺,支持主設(shè)備(搭載OpenHarmony的智慧屏設(shè)備)啟動從設(shè)備(IP Camera、運動手表等小內(nèi)存OpenHarmony設(shè)備)FA的能力。
以智慧屏節(jié)目開播提醒為例,智慧屏上在喜歡的節(jié)目菜單中,點擊“開播后提醒我”按鈕,等節(jié)目開播后,智慧屏會拉起運動手表上的節(jié)目開播提醒FA。通過該FA用戶可以快速知道喜歡的節(jié)目已經(jīng)開始,達到協(xié)同互助的作用。
FA : Feature Ability代表有界面的Ability,用于與用戶進行交互。
遠程啟動:即跨設(shè)備啟動FA,與本地啟動FA相對應。
開源鴻蒙系統(tǒng)里的應用程序以Ability為單位,分為FA和PA, 可以簡單理解為FA就是有界面的應用程序。
分布式服務平臺
分布式任務調(diào)度的前提,是設(shè)備必須建立分布式服務平臺,并且注冊自身能力。
開源鴻蒙支持3種體量的設(shè)備:輕量、小型、標準。
在標準設(shè)備里,開源鴻蒙默認已經(jīng)開啟了分布式服務平臺,開發(fā)者一般無需做額外工作,即可使用分布式任務調(diào)度功能。
而輕量和小型設(shè)備則需要自行在啟動代碼中實現(xiàn)分布式服務平臺功能調(diào)用,具體可以參考【分布式軟總線子系統(tǒng)】。相關(guān)代碼倉及調(diào)用API可以參考:【分布式軟總線】,【分布式軟總線lite】。
同一個局域網(wǎng)
在上述代碼倉的說明中,一再強調(diào)了:
需要保證發(fā)現(xiàn)端設(shè)備與被發(fā)現(xiàn)端設(shè)備在同一個局域網(wǎng)內(nèi)
是因為目前開源鴻蒙系統(tǒng)使用了coap協(xié)議,并且暫時只支持coap協(xié)議。從源代碼中可以看到,以后應該會擴展到BLE、USB等方式。
- /**
- * @brief Enumerates media, such as Bluetooth, Wi-Fi and USB, used for publishing services.
- *
- * Currently, the media can only be set to coap.
- *
- */
- typedef enum {
- /** Automatic medium selection */
- AUTO = 0,
- /** Bluetooth */
- BLE = 1,
- /** Wi-Fi */
- COAP = 2,
- /** USB */
- USB = 3,
- } ExchangeMedium;
開源鴻蒙的coap協(xié)議默認使用的端口是5684,在局域網(wǎng)通過udp廣播方式發(fā)布。如果調(diào)試過程中找不到設(shè)備,可以通過這個端口抓包分析。
- #define COAP_DEFAULT_PORT 5684
分布式任務調(diào)度流程
手頭正好有兩塊支持開源鴻蒙標準系統(tǒng)的開發(fā)板Hi3516D,因此以標準系統(tǒng)的分布式任務調(diào)度為例,說明開源鴻蒙系統(tǒng)的分布式任務調(diào)度流程。輕量系統(tǒng)和小型系統(tǒng)除了開發(fā)語言不同,基本步驟是一致的。
開源鴻蒙系統(tǒng)開發(fā)FA目前只支持js/eTS語言。
這個demo參考了分布式計算器,為說明方便,做了大量簡化處理,并且此處忽略了錯誤處理。
具體api參考代碼倉:DeviceManager組件。
步驟1:創(chuàng)建設(shè)備管理器
- import deviceManager from '@ohos.distributedHardware.deviceManager';
- let self = this;
- deviceManager.createDeviceManager("com.example.myapplication", (err, val)=>{self.deviceManager_ = val;});
使用DeviceManager相關(guān)接口之前,需要通過createDeviceManager接口創(chuàng)建DeviceManager實例;
步驟2:獲取可信設(shè)備列表
- var array = this.deviceManager_.getTrustedDeviceListSync();
步驟3:注冊周邊設(shè)備動態(tài)監(jiān)控回調(diào)函數(shù)
- this.deviceManager_.on('deviceFound', (data) => {
- let extraInfo = {
- "targetPkgName": 'com.example.myapplication',
- "appName": '分布式例子',
- "appDescription": '一個簡單的分布式例子',
- "business": '0'
- };
- let authParam = {
- "authType": 1,
- "appIcon": '',
- "appThumbnail": '',
- "extraInfo": extraInfo
- };
- self.deviceManager_.authenticateDevice(data.device, authParam, (err) => { ... });
- });
- this.deviceManager_.on('deviceStateChange', (data) => { ... });
步驟4:發(fā)現(xiàn)周邊新設(shè)備,并認證
- SUBSCRIBE_ID = Math.floor(65536 * Math.random());
- var info = {
- subscribeId: SUBSCRIBE_ID,
- mode: 0xAA,
- medium: 2,
- freq: 2,
- isSameAccount: false,
- isWakeRemote: true,
- capability: 0
- };
- this.deviceManager_.startDeviceDiscover(info);
新設(shè)備需要認證才能互聯(lián)使用。開源鴻蒙系統(tǒng)沒有用戶注冊機制,因此認證需要另外開發(fā)框架支持,開源鴻蒙在標準系統(tǒng)提供了一個簡單的HAP程序支持彈窗PIN碼認證機制,可以簡單使用。
當前版本只支持PIN碼認證,需要提供PIN碼認證的授權(quán)提示界面、PIN碼顯示界面、PIN碼輸入界面;
當前,由于系統(tǒng)通過native層直接進行彈窗的能力尚不具備,這里使用一個臨時的FA來進行對應界面的彈窗。
該FA為:DeviceManager_UI.hap,作為系統(tǒng)應用進行預置。
具體行為是:
- 遠程設(shè)備在屏幕顯示一個巨大的6位數(shù)字PIN碼
- 控制設(shè)備彈出一個PIN碼輸入窗口
- 用戶在控制設(shè)備輸入遠程設(shè)備所顯示的PIN碼,通過驗證即可繼續(xù)遠程控制
- PIN碼輸入成功后,該設(shè)備成為可信設(shè)備存儲于系統(tǒng),下次再次連接時不需要再次驗證
步驟5:遠程調(diào)用FA
以上步驟1~步驟4是標準的周圍設(shè)備管理步驟,因此可以封裝成函數(shù)庫,方便后續(xù)使用。
在獲取到可信設(shè)備數(shù)組后,可以在適當?shù)膹棿盎蛘哌x擇界面,讓用戶選擇其中一個進行連接。
- findDevices: function(){
- let self = this;
- this.remoteDevices.registerDeviceListCallback(() => {
- var list = new Array();
- var devs = self.remoteDevices.deviceList;
- console.info('myapplication: on remote device updated, count=' + devs.length);
- for (var i = 0; i < devs.length; i++) {
- console.info('myapplication: device ' + i + '/' + devs.length +
- ' deviceId=' + devs[i].deviceId + ' deviceName=' + devs[i].deviceName
- + ' deviceType=' + devs[i].deviceType);
- list[i + 1] = {
- name: devs[i].deviceName,
- did: devs[i].deviceId
- };
- }
- self.devList = list;
- });
- },
啟動遠程FA的程序:
- import featureAbility from '@ohos.ability.featureability';
- ......
- featureAbility.startAbility({
- want:{
- bundleName: 'com.example.myapplication',
- abilityName: 'com.example.myapplication.MainAbility',
- deviceId: this.devList[idx].did,
- parameters: {
- isFA: 'FA'
- }
- }
- }).then((data)=>{
- console.log("myapplication: start ability finished:" + JSON.stringify(data));
- });
遠程設(shè)備收到請求后,就會以對應的參數(shù)啟動相應的FA,并且在啟動時可以獲取到參數(shù):
- onReady() {
- featureAbility.getWant((error, want) => {
- console.info('myapplication: featureAbility.getWant =' + JSON.stringify(want.parameters));
- // 這里isFA就是上面遠程請求的參數(shù)
- if (want.parameters.isFA && want.parameters.isFA === 'FA') {
- this.initKVManager(()=>{
- console.log('myapplication: kvmanager started.')
- });
- }
- else{
- this.findDevices();
- }
- });
- },
具體api可以參考華為鴻蒙開發(fā)文檔,請注意里面部分內(nèi)容可能與開源鴻蒙系統(tǒng)有區(qū)別,請自行確定。
編譯運行
以上步驟,均已在DevEco Studio 3.0.0.600 x64中編寫成功,并且在兩臺Hi3516D設(shè)備間成功運行,附代碼(分布式遠程啟動.zip)。
想在開源鴻蒙系統(tǒng)上安裝HAP程序,必須要先進行簽名,并且在DevEco Studio中進行相關(guān)設(shè)置。具體步驟參考開源鴻蒙文檔。
上傳安裝HAP程序,需要使用開發(fā)工具hdc,具體參考文檔。
小結(jié)
開源鴻蒙系統(tǒng)的分布式任務調(diào)度基本功能已經(jīng)初步完善了,使用文檔比較分散,需要到各個子系統(tǒng)去查閱,略有不便。
下一步,學習一下分布式軟總線、分布式數(shù)據(jù),看看開源鴻蒙系統(tǒng)是如何封裝應用之間數(shù)據(jù)交互能力的。
另外看源代碼,開源鴻蒙系統(tǒng)已經(jīng)有分布式應用流轉(zhuǎn)(遷移)運行功能,有時間可以學習一下。
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)