一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

鴻蒙開(kāi)發(fā)【分布式任務(wù)調(diào)度】解析

jf_46214456 ? 來(lái)源:jf_46214456 ? 作者:jf_46214456 ? 2024-01-29 18:03 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

鴻蒙OS 分布式任務(wù)調(diào)度概述

HarmonyO S中,分布式任務(wù)調(diào)度平臺(tái)對(duì)搭載 HarmonyOS 的多設(shè)備構(gòu)筑的“超級(jí)虛擬終端”提供統(tǒng)一的組件管理能力,為應(yīng)用定義統(tǒng)一的能力基線、接口形式、數(shù)據(jù)結(jié)構(gòu)、服務(wù)描述語(yǔ)言,屏蔽硬件差異;支持遠(yuǎn)程啟動(dòng)、遠(yuǎn)程調(diào)用、業(yè)務(wù)無(wú)縫遷移等分布式任務(wù)。

分布式任務(wù)調(diào)度平臺(tái)在底層實(shí)現(xiàn) Ability(分布式任務(wù)調(diào)度的基本組件)跨設(shè)備的啟動(dòng)/關(guān)閉、連接及斷開(kāi)連接以及遷移等能力,實(shí)現(xiàn)跨設(shè)備的組件管理:

  • 啟動(dòng)和關(guān)閉:向開(kāi)發(fā)者提供管理遠(yuǎn)程 Ability 的能力,即支持啟動(dòng) Page 模板的 Ability,以及啟動(dòng)、關(guān)閉 Service 和 Data 模板的 Ability。
  • 連接和斷開(kāi)連接:向開(kāi)發(fā)者提供跨設(shè)備控制服務(wù)( Service 和 Data 模板的 Ability )的能力,開(kāi)發(fā)者可以通過(guò)與遠(yuǎn)程服務(wù)連接及斷開(kāi)連接實(shí)現(xiàn)獲取或注銷(xiāo)跨設(shè)備管理服務(wù)的對(duì)象,達(dá)到和本地一致的服務(wù)調(diào)度。
  • 遷移能力:向開(kāi)發(fā)者提供跨設(shè)備業(yè)務(wù)的無(wú)縫遷移能力,開(kāi)發(fā)者可以通過(guò)調(diào)用 Page 模板 Ability 的遷移接口,將本地業(yè)務(wù)無(wú)縫遷移到指定設(shè)備中,打通設(shè)備間壁壘。

約束與限制

  • 開(kāi)發(fā)者需要在 Intent 中設(shè)置支持分布式的標(biāo)記(例如:Intent.FLAG_ABILITYSLICE_MULTI_DEVICE 表示該應(yīng)用支持分布式調(diào)度),否則將無(wú)法獲得分布式能力。
  • 開(kāi)發(fā)者通過(guò)在 config.json 中添加分布式數(shù)據(jù)傳輸?shù)臋?quán)限申請(qǐng):{"name": "ohos.permission.servicebus.ACCESS_SERVICE"},獲取跨設(shè)備連接的能力。
  • PA( Particle Ability,Service 和 Data 模板的 Ability)的調(diào)用支持連接及斷開(kāi)連接、啟動(dòng)及關(guān)閉這四類(lèi)行為,在進(jìn)行調(diào)度時(shí):
  • 開(kāi)發(fā)者必須在 Intent 中指定 PA 對(duì)應(yīng)的 bundleName 和 abilityName。
  • 當(dāng)開(kāi)發(fā)者需要跨設(shè)備啟動(dòng)、關(guān)閉或連接 PA 時(shí),需要在 Intent 中指定對(duì)端設(shè)備的 deviceId。開(kāi)發(fā)者可通過(guò)如設(shè)備管理類(lèi) DeviceManager 提供的 getDeviceList 獲取指定條件下匿名化處理的設(shè)備列表,實(shí)現(xiàn)對(duì)指定設(shè)備 PA 的啟動(dòng)/關(guān)閉以及連接管理。
  • FA(Feature Ability,Page 模板的 Ability)的調(diào)用支持啟動(dòng)和遷移行為,在進(jìn)行調(diào)度時(shí):
  • 當(dāng)啟動(dòng) FA 時(shí),需要開(kāi)發(fā)者在 Intent 中指定對(duì)端設(shè)備的 deviceId、bundleName 和 abilityName。
  • FA 的遷移實(shí)現(xiàn)相同 bundleName 和 abilityName 的 FA 跨設(shè)備遷移,因此需要指定遷移設(shè)備的 deviceId。

鴻蒙OS 發(fā)布式任務(wù)調(diào)度開(kāi)發(fā)指導(dǎo)

場(chǎng)景介紹

開(kāi)發(fā)者在應(yīng)用中集成分布式調(diào)度能力,通過(guò)調(diào)用指定能力的分布式接口,實(shí)現(xiàn)跨設(shè)備能力調(diào)度。根據(jù) Ability 模板及意圖的不同,分布式任務(wù)調(diào)度向開(kāi)發(fā)者提供以下六種能力:?jiǎn)?dòng)遠(yuǎn)程 FA、啟動(dòng)遠(yuǎn)程 PA、關(guān)閉遠(yuǎn)程 PA、連接遠(yuǎn)程 PA、斷開(kāi)連接遠(yuǎn)程 PA 和 FA 跨設(shè)備遷移。下面以設(shè)備 A(本地設(shè)備)和設(shè)備 B(遠(yuǎn)端設(shè)備)為例,進(jìn)行場(chǎng)景介紹:

  • 設(shè)備 A 啟動(dòng)設(shè)備 B 的 FA:在設(shè)備 A 上通過(guò)本地應(yīng)用提供的啟動(dòng)按鈕,啟動(dòng)設(shè)備 B 上對(duì)應(yīng)的 FA。例如:設(shè)備 A 控制設(shè)備 B 打開(kāi)相冊(cè),只需開(kāi)發(fā)者在啟動(dòng) FA 時(shí)指定打開(kāi)相冊(cè)的意圖即可。
  • 設(shè)備 A 啟動(dòng)設(shè)備 B 的 PA:在設(shè)備 A 上通過(guò)本地應(yīng)用提供的啟動(dòng)按鈕,啟動(dòng)設(shè)備 B 上指定的 PA。例如:開(kāi)發(fā)者在啟動(dòng)遠(yuǎn)程服務(wù)時(shí)通過(guò)意圖指定音樂(lè)播放服務(wù),即可實(shí)現(xiàn)設(shè)備 A 啟動(dòng)設(shè)備 B 音樂(lè)播放的能力。
  • 設(shè)備 A 關(guān)閉設(shè)備 B 的 PA:在設(shè)備 A 上通過(guò)本地應(yīng)用提供的關(guān)閉按鈕,關(guān)閉設(shè)備 B 上指定的 PA。類(lèi)似啟動(dòng)的過(guò)程,開(kāi)發(fā)者在關(guān)閉遠(yuǎn)程服務(wù)時(shí)通過(guò)意圖指定音樂(lè)播放服務(wù),即可實(shí)現(xiàn)關(guān)閉設(shè)備 B 上該服務(wù)的能力。
  • 設(shè)備 A 連接設(shè)備 B 的 PA:在設(shè)備 A 上通過(guò)本地應(yīng)用提供的連接按鈕,連接設(shè)備 B 上指定的 PA。連接后,通過(guò)其他功能相關(guān)按鈕實(shí)現(xiàn)控制對(duì)端 PA 的能力。通過(guò)連接關(guān)系,開(kāi)發(fā)者可以實(shí)現(xiàn)跨設(shè)備的同步服務(wù)調(diào)度,實(shí)現(xiàn)如大型計(jì)算任務(wù)互助等價(jià)值場(chǎng)景。
  • 設(shè)備 A 與設(shè)備 B 的 PA 斷開(kāi)連接:在設(shè)備 A 上通過(guò)本地應(yīng)用提供斷開(kāi)連接的按鈕,將之前已連接的 PA 斷開(kāi)連接。
  • 設(shè)備 A 的 FA 遷移至設(shè)備B:設(shè)備 A 上通過(guò)本地應(yīng)用提供的遷移按鈕,將設(shè)備 A 的業(yè)務(wù)無(wú)縫遷移到設(shè)備B中。通過(guò)業(yè)務(wù)遷移能力,打通設(shè)備 A 和設(shè)備 B 間的壁壘,實(shí)現(xiàn)如文檔跨設(shè)備編輯、視頻從客廳到房間跨設(shè)備接續(xù)播放等場(chǎng)景。

接口說(shuō)明

分布式調(diào)度平臺(tái)提供的連接和斷開(kāi)連接 PA、啟動(dòng)遠(yuǎn)程 FA、啟動(dòng)和關(guān)閉 PA 以及遷移 FA 的能力,是實(shí)現(xiàn)更多價(jià)值性場(chǎng)景的基礎(chǔ)。

  • 連接遠(yuǎn)程PA

connectAbility(Intent intent, IAbilityConnection conn)接口提供連接指定設(shè)備上 PA 的能力,Intent 中指定待連接 PA 的設(shè)備 deviceId、bundleName 和 abilityName。當(dāng)連接成功后,通過(guò)在 conn 定義的 onAbilityConnectDone 回調(diào)中獲取對(duì)端 PA 的服務(wù)代理,兩者的連接關(guān)系則由 conn 維護(hù)。具體的參數(shù)定義如下表所示:

參數(shù)名<>類(lèi)型<>說(shuō)明<>
intent<>ohos.aafwk.content.Intent<>開(kāi)發(fā)者需在 intent 對(duì)應(yīng)的Operation 中指定待連接 PA 的設(shè)備 deviceId、bundleName 和 abilityName。<>
conn<>ohos.aafwk.ability.IAbilityConnection<>當(dāng)連接成功或失敗時(shí),作為連接關(guān)系的回調(diào)接口。該接口提供連接完成和斷開(kāi)連接完成時(shí)的處理邏輯,開(kāi)發(fā)者可根據(jù)具體的場(chǎng)景進(jìn)行定義。<>
  • 啟動(dòng)遠(yuǎn)程FA/PA startAbility(Intent intent) 接口提供啟動(dòng)指定設(shè)備上 FA 和 PA 的能力,Intent 中指定待啟動(dòng) FA/PA 的設(shè)備 deviceId、bundleName 和 abilityName。具體參數(shù)定義如下表所示:
參數(shù)名<>類(lèi)型<>說(shuō)明<>
intent<>ohos.aafwk.content.Intent<>當(dāng)開(kāi)發(fā)者需要調(diào)用該接口啟動(dòng)遠(yuǎn)程 PA 時(shí),需要指定待啟動(dòng) PA 的設(shè)備 deviceId、bundleName 和 abilityName。若不指定設(shè)備deviceId,則無(wú)法跨設(shè)備調(diào)用 PA。類(lèi)似地,在啟動(dòng)FA時(shí),也需要開(kāi)發(fā)者指定啟動(dòng) FA 的設(shè)備 deviceId、bundleName 和 abilityName。<>

分布式調(diào)度平臺(tái)還會(huì)提供與上述功能相對(duì)應(yīng)的斷開(kāi)遠(yuǎn)程 PA 的連接和關(guān)閉遠(yuǎn)程 PA 的接口,相關(guān)的參數(shù)與連接、啟動(dòng)的接口類(lèi)似。

1.斷開(kāi)遠(yuǎn)程 PA 連接:disconnectAbility (IAbilityConnection conn)。 2.關(guān)閉遠(yuǎn)程 PA:boolean stopAbility (Intent intent)。

  • 遷移FA

continueAbility(String deviceId)接口提供將本地FA遷移到指定設(shè)備上的能力,需要開(kāi)發(fā)者在調(diào)用時(shí)指定目標(biāo)設(shè)備的 deviceId。具體參數(shù)定義如下表所示:

說(shuō)明

Ability 和 AbilitySlice 類(lèi)均需要實(shí)現(xiàn) IAbilityContinuation 及其方法,才可以實(shí)現(xiàn) FA 遷移。

參數(shù)名<>類(lèi)型<>說(shuō)明<>
deviceId<>String<>當(dāng)開(kāi)發(fā)者需要調(diào)用該接口將本地 FA 遷移時(shí),需要指定目標(biāo)設(shè)備的 deviceId。<>

開(kāi)發(fā)步驟

  • 導(dǎo)入功能依賴(lài)的包。
// 以下依賴(lài)包含分布式調(diào)度平臺(tái)開(kāi)放的接口,用于:連接/斷開(kāi)連接遠(yuǎn)程 PA、啟動(dòng)遠(yuǎn)程 FA、通過(guò)連接關(guān)系注冊(cè)的回調(diào)函數(shù) onAbilityConnectDon e中返回的對(duì)端 PA 的代理,實(shí)現(xiàn)對(duì)PA的控制
   import ohos.aafwk.ability.AbilitySlice;
   import ohos.aafwk.ability.IAbilityConnection;
   import ohos.aafwk.content.Intent;
   import ohos.aafwk.content.Operation;
   import ohos.bundle.ElementName;
   // 為了實(shí)現(xiàn)遷移能力,需要引入傳遞遷移所需數(shù)據(jù)的包以及實(shí)現(xiàn)遷移能力的接口。
   import ohos.aafwk.ability.IAbilityContinuation;
   import ohos.aafwk.content.IntentParams;
   // 為了實(shí)現(xiàn)跨設(shè)備指令及數(shù)據(jù)通信,需要集成 HarmonyOS 提供的 RPC 接口
   import ohos.rpc.IRemoteObject;
   import ohos.rpc.IRemoteBroker;
   import ohos.rpc.MessageParcel;
   import ohos.rpc.MessageOption;
   import ohos.rpc.RemoteException;
   import ohos.rpc.RemoteObject;
   //(可選)多設(shè)備場(chǎng)景下涉及設(shè)備選擇,為此需要引入組網(wǎng)設(shè)備發(fā)現(xiàn)的能力
   import ohos.distributedschedule.interwork.DeviceInfo;
   import ohos.distributedschedule.interwork.DeviceManager;
   // (可選)設(shè)計(jì)界面相關(guān)的包函數(shù),對(duì) FA 界面及按鈕進(jìn)行繪制
   import ohos.agp.components.Button;
   import ohos.agp.components.Component;
   import ohos.agp.components.Component.ClickedListener;
   import ohos.agp.components.ComponentContainer.LayoutConfig;
   import ohos.agp.components.element.ShapeElement;
   import ohos.agp.components.PositionLayout;
   import ohos.agp.components.PositionLayout;
import ohos.agp.components.PositionLayout;
  • (可選)編寫(xiě)一個(gè)基本的 FA 用于使用分布式能力。
// 調(diào)用 AbilitySlice 模板實(shí)現(xiàn)一個(gè)用于控制基礎(chǔ)功能的 FA
   // Ability 和 AbilitySlice 類(lèi)均需要實(shí)現(xiàn) IAbilityContinuation 及其方法,才可以實(shí)現(xiàn) FA 遷移。AbilitySlice 的代碼示例如下
   public class SampleSlice extends AbilitySlice implements IAbilityContinuation {
       @Override
       public void onStart(Intent intent) {
           super.onStart(intent);
           // 開(kāi)發(fā)者可以自行進(jìn)行界面設(shè)計(jì)
           // 為按鈕設(shè)置統(tǒng)一的背景色
           // 例如通過(guò)PositionLayout指定大小可以實(shí)現(xiàn)簡(jiǎn)單界面
           PositionLayout layout = new PositionLayout(this);
           LayoutConfig config = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT);
           layout.setLayoutConfig(config);
           ShapeElement buttonBg = new ShapeElement();
           buttonBg.setRgbColor(new RgbColor(0,125,255));
           addComponents(layout, buttonBg, config);
           super.setUIContent(layout);
       }
    
       @Override
       public void onInactive() {
           super.onInactive();
       }
    
       @Override
       public void onActive() {
           super.onActive();
       }
    
       @Override
       public void onBackground() {
           super.onBackground();
       }
    
       @Override
       public void onForeground(Intent intent) {
           super.onForeground(intent);
       }
    
       @Override
       public void onStop() {
           super.onStop();
       }
   }
   }
}

說(shuō)明

此步驟展示了一個(gè)簡(jiǎn)單 FA 的實(shí)現(xiàn)過(guò)程,實(shí)際開(kāi)發(fā)中請(qǐng)開(kāi)發(fā)者根據(jù)需要進(jìn)行設(shè)計(jì)。

  • (可選)為不同的能力設(shè)置相應(yīng)的控制按鈕。
// 建議開(kāi)發(fā)者按照自己的界面進(jìn)行按鈕設(shè)計(jì)
   // 開(kāi)發(fā)者可以自行實(shí)現(xiàn)如 createButton 的方法,新建一個(gè)顯示文字 text,背景色為 buttonBg 以及大小尺寸位置符合 config 設(shè)置的按鈕,用來(lái)與用戶發(fā)生交互
   // private Button createButton(String text, ShapeElement buttonBg, LayoutConfig config)
   // 按照順序在 PositionLayout 中依次添加按鈕的示例
   private void addComponents(PositionLayout linear, ShapeElement buttonBg, LayoutConfig config) {
       // 構(gòu)建遠(yuǎn)程啟動(dòng)FA的按鈕
       btnStartRemoteFA = createButton("StartRemoteFA", buttonBg, config);
       btnStartRemoteFA.setClickedListener(mStartRemoteFAListener);
       linear.addComponent(btnStartRemoteFA);
       // 構(gòu)建遠(yuǎn)程啟動(dòng)PA的按鈕
       btnStartRemotePA = createButton("StartRemotePA", buttonBg, config);
       btnStartRemotePA.setClickedListener(mStartRemotePAListener);
       linear.addComponent(btnStartRemotePA);
       // 構(gòu)建遠(yuǎn)程關(guān)閉PA的按鈕
       btnStopRemotePA = createButton("StopRemotePA", buttonBg, config);
       btnStopRemotePA.setClickedListener(mStopRemotePAListener);
       linear.addComponent(btnStopRemotePA);
       // 構(gòu)建連接遠(yuǎn)程PA的按鈕
       btnConnectRemotePA = createButton("ConnectRemotePA", buttonBg, config);
       btnConnectRemotePA.setClickedListener(mConnectRemotePAListener);
       linear.addComponent(btnConnectRemotePA);
       // 構(gòu)建控制連接PA的按鈕
       btnControlRemotePA = createButton("ControlRemotePA", buttonBg, config);
       btnControlRemotePA.setClickedListener(mControlPAListener);
       linear.addComponent(btnControlRemotePA);
       // 構(gòu)建與遠(yuǎn)程PA斷開(kāi)連接的按鈕
       btnDisconnectRemotePA = createButton("DisconnectRemotePA", buttonBg, config);
       btnDisconnectRemotePA.setClickedListener(mDisconnectRemotePAListener);
       linear.addComponent(btnDisconnectRemotePA);
       // 構(gòu)建遷移FA的按鈕
       btnContinueRemoteFA = createButton("ContinueRemoteFA", buttonBg, config);
       btnContinueRemoteFA.setClickedListener(mContinueAbilityListener);
       linear.addComponent(btnContinueRemoteFA);
   }
   }
}

說(shuō)明

此處只展示了基于按鈕控制的能力調(diào)度方法,實(shí)際開(kāi)發(fā)中請(qǐng)開(kāi)發(fā)者根據(jù)需要選擇能力調(diào)度方式。代碼示例中未體現(xiàn)按鈕如位置、樣式等具體的設(shè)置方法,詳請(qǐng)參考 JAVA UI框架。

  • 通過(guò)設(shè)備管理 DeviceManager 提供的 getDeviceList 接口獲取設(shè)備列表,用于指定目標(biāo)設(shè)備。
// ISelectResult 是一個(gè)自定義接口,用來(lái)處理指定設(shè)備 deviceId 后執(zhí)行的行為
    interface ISelectResult {
        void onSelectResult(String deviceId);
    }
    
   // 獲得設(shè)備列表,開(kāi)發(fā)者可在得到的在線設(shè)備列表中選擇目標(biāo)設(shè)備執(zhí)行操作
   private void scheduleRemoteAbility(ISelectResult listener) {
       // 調(diào)用DeviceManager的getDeviceList接口,通過(guò)FLAG_GET_ONLINE_DEVICE標(biāo)記獲得在線設(shè)備列表
       List< DeviceInfo > onlineDevices = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
       // 判斷組網(wǎng)設(shè)備是否為空
       if (onlineDevices.isEmpty()) {
           listener.onSelectResult(null);
           return;
       }
       int numDevices = onlineDevices.size();
       ArrayList< String > deviceIds = new ArrayList<  >(numDevices);
       ArrayList< String > deviceNames = new ArrayList<  >(numDevices);
       onlineDevices.forEach((device) - > {
           deviceIds.add(device.getDeviceId());
           deviceNames.add(device.getDeviceName());
       });
       // 以選擇首個(gè)設(shè)備作為目標(biāo)設(shè)備為例
       // 開(kāi)發(fā)者也可按照具體場(chǎng)景,通過(guò)別的方式進(jìn)行設(shè)備選擇
       String selectDeviceId = deviceIds.get(0);
       listener.onSelectResult(selectDeviceId);    
   }
   }
}

上述實(shí)例中涉及對(duì)在線組網(wǎng)設(shè)備的查詢(xún),該項(xiàng)能力需要開(kāi)發(fā)者在對(duì)應(yīng)的 config.json 中聲明獲取設(shè)備列表及設(shè)備信息的權(quán)限,如下所示:

{
       "reqPermissions": [
           {
               "name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
           }, 
           {
               "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
           }, 
           {
               "name": "ohos.permission.GET_BUNDLE_INFO"
           }
       ]
   }
   }
}
  • 為啟動(dòng)遠(yuǎn)程 FA 的按鈕設(shè)置點(diǎn)擊回調(diào),實(shí)現(xiàn)啟動(dòng)遠(yuǎn)程 FA 的能力。
// 啟動(dòng)一個(gè)指定 bundleName 和 abilityName 的 FA
   private ClickedListener mStartRemoteFAListener = new ClickedListener() {
       @Override
       public void onClick(Component arg0) {
           // 啟動(dòng)遠(yuǎn)程PA
           scheduleRemoteAbility(new ISelectResult() {
               @Override
               void onSelectResult(String deviceId) {
                   if (deviceId != null) {
                       Intent intent = new Intent();
                       // 通過(guò)scheduleRemoteAbility指定目標(biāo)設(shè)備deviceId
                       // 指定待啟動(dòng)FA的bundleName和abilityName
                       // 例如:bundleName = "com.huawei.helloworld"
                       //       abilityName = "com.huawei.helloworld.SampleFeatureAbility"
                       // 設(shè)置分布式標(biāo)記,表明當(dāng)前涉及分布式能力
                       Operation operation = new Intent.OperationBuilder()
                               .withDeviceId(deviceId)
                               .withBundleName(bundleName)
                               .withAbilityName(abilityName)
                               .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                               .build();
                       intent.setOperation(operation);
                       // 通過(guò)AbilitySlice包含的startAbility接口實(shí)現(xiàn)跨設(shè)備啟動(dòng)FA
                       startAbility(intent);
                   }
               }
           });
       }
   };
   };
};
  • 為啟動(dòng)和關(guān)閉 PA 定義回調(diào),實(shí)現(xiàn)啟動(dòng)和關(guān)閉 PA 的能力。

對(duì)于 PA 的啟動(dòng)、關(guān)閉、連接等操作都需要開(kāi)發(fā)者提供目標(biāo)設(shè)備的 deviceId。開(kāi)發(fā)者可以通過(guò) DeviceManager 相關(guān)接口得到當(dāng)前組網(wǎng)下的設(shè)備列表,并以彈窗的形式供用戶選擇,也可以按照實(shí)際需要實(shí)現(xiàn)其他個(gè)性化的處理方式。在點(diǎn)擊事件回調(diào)函數(shù)中,需要開(kāi)發(fā)者指定得到 deviceId 后的處理邏輯,即實(shí)現(xiàn)類(lèi)似上例中 listener.onSelectResult(String deviceId) 的方法,代碼示例如下:

// 啟動(dòng)遠(yuǎn)程 PA
   private ClickedListener mStartRemotePAListener = new ClickedListener() {
       @Override
       public void onClick(Component arg0) {
           // 啟動(dòng)遠(yuǎn)程PA
           scheduleRemoteAbility(new ISelectResult() {
               @Override
               void onSelectResult(String deviceId) {
                   if (deviceId != null) {
                       Intent intentToStartPA = new Intent();
                       // bundleName和abilityName與待啟動(dòng)PA對(duì)應(yīng)
                       // 例如:bundleName = "com.huawei.helloworld"
                       //       abilityName = "com.huawei.helloworld.SampleParticleAbility"
                       Operation operation = new Intent.OperationBuilder()
                               .withDeviceId(deviceId)
                               .withBundleName(bundleName)
                               .withAbilityName(abilityName)
                               .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                               .build();
                       intentToStartPA.setOperation(operation);
                       startAbility(intentToStartPA);
                   }
               }
           });
       }
   };
    
   // 關(guān)閉遠(yuǎn)程 PA,和啟動(dòng)類(lèi)似開(kāi)發(fā)者需要指定待關(guān)閉 PA 對(duì)應(yīng)的 bundleName 和 abilityName
   private ClickedListener mStopRemotePAListener = new ClickedListener() {
       @Override
       public void onClick(Component arg0) {
           scheduleRemoteAbility(new ISelectResult() {
               @Override
               void onSelectResult(String deviceId) {
                   if (deviceId != null) {
                       Intent intentToStopPA = new Intent();
                       // bundleName和abilityName與待關(guān)閉PA對(duì)應(yīng)
                       // 例如:bundleName = "com.huawei.helloworld"
                       //       abilityName = "com.huawei.helloworld.SampleParticleAbility"
                       Operation operation = new Intent.OperationBuilder()
                               .withDeviceId(deviceId)
                               .withBundleName(bundleName)
                               .withAbilityName(abilityName)
                               .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                               .build();
                       intentToStopPA.setOperation(operation);
                       stopAbility(intentToStopPA);
                   }
               }
           });
       }
   };
   };
};

說(shuō)明

啟動(dòng)和關(guān)閉的行為類(lèi)似,開(kāi)發(fā)者只需在 Intent 中指定待調(diào)度 PA 的 deviceId、bundleName 和 abilityName,并以 operation 的形式封裝到 Intent 內(nèi)。通過(guò) AbilitySlice(Ability)包含的 startAbility()和 stopAbility()接口即可實(shí)現(xiàn)相應(yīng)功能。

  • 設(shè)備 A 連接設(shè)備 B 側(cè)的 PA,利用連接關(guān)系調(diào)用該 PA 執(zhí)行特定任務(wù),以及斷開(kāi)連接。
// 當(dāng)連接完成時(shí),用來(lái)提供管理已連接 PA 的能力
   private MyRemoteProxy mProxy = null;
   // 用于管理連接關(guān)系
   private IAbilityConnection conn = new IAbilityConnection() {
       @Override
       public void onAbilityConnectDone(ElementName element, IRemoteObject remote, int resultCode) {
           // 跨設(shè)備PA連接完成后,會(huì)返回一個(gè)序列化的IRemoteObject對(duì)象
           // 通過(guò)該對(duì)象得到控制遠(yuǎn)端服務(wù)的代理
           mProxy = new MyRemoteProxy(remote);
           btnConnectRemotePA.setText("connectRemoteAbility done");
        }
    
       @Override
       public void onAbilityDisconnectDone(ElementName element, int resultCode) {
           // 當(dāng)已連接的遠(yuǎn)端PA關(guān)閉時(shí),會(huì)觸發(fā)該回調(diào)
           // 支持開(kāi)發(fā)者按照返回的錯(cuò)誤信息進(jìn)行PA生命周期管理
           disconnectAbility(conn);
       }
   };
   };
};

僅通過(guò)啟動(dòng)/關(guān)閉兩種方式對(duì) PA 進(jìn)行調(diào)度無(wú)法應(yīng)對(duì)需長(zhǎng)期交互的場(chǎng)景,因此,分布式任務(wù)調(diào)度平臺(tái)向開(kāi)發(fā)者提供了跨設(shè)備PA連接及斷開(kāi)連接的能力。為了對(duì)已連接 PA 進(jìn)行管理,開(kāi)發(fā)者需要實(shí)現(xiàn)一個(gè)滿足 IAbilityConnection 接口的連接狀態(tài)檢測(cè)實(shí)例,通過(guò)該實(shí)例可以對(duì)連接及斷開(kāi)連接完成時(shí)設(shè)置具體的處理邏輯,例如:獲取控制對(duì)端 PA 的代理等。進(jìn)一步為了使用該代理跨設(shè)備調(diào)度 PA,開(kāi)發(fā)者需要在本地及對(duì)端分別實(shí)現(xiàn)對(duì)外接口一致的代理。一個(gè)具備加法能力的代理示例如下:

// 以連接提供加法計(jì)算能力的 PA 為例。為了提供跨設(shè)備連接能力,需要在本地發(fā)起連接側(cè)和對(duì)端被連接側(cè)分別實(shí)現(xiàn)代理。
   // 發(fā)起連接側(cè)的代理示例如下
   public class MyRemoteProxy implements IRemoteBroker{
       private static final int ERR_OK = 0;
       private static final int COMMAND_PLUS = IRemoteObject.MIN_TRANSACTION_ID;
       private final IRemoteObject remote;
    
       public MyRemoteProxy(
           /* [in] */ IRemoteObject remote) {
           this.remote = remote;
       }
    
       @Override
       public IRemoteObject asObject() {
           return remote;
       }
    
       public int plus(
           /* [in] */ int a,
           /* [in] */ int b) throws RemoteException {
           MessageParcel data = MessageParcel.obtain();
           MessageParcel reply = MessageParcel.obtain();
           // option不同的取值,決定采用同步或異步方式跨設(shè)備控制PA
           // 本例需要同步獲取對(duì)端PA執(zhí)行加法的結(jié)果,因此采用同步的方式,即MessageOption.TF_SYNC
           // 具體MessageOption的設(shè)置,可參考相關(guān)API文檔
           MessageOption option = new MessageOption(MessageOption.TF_SYNC);
           data.writeInt(a);
           data.writeInt(b);
    
           try {
               remote.sendRequest(COMMAND_PLUS, data, reply, option);
               int ec = reply.readInt();
               if (ec != ERR_OK) {
                   throw new RemoteException();
               }
               int result = reply.readInt();
               return result;
           } catch (RemoteException e) {
               throw new RemoteException();
           } finally {
               data.reclaim();
               reply.reclaim();
           }
       }
   }
   }
}

此外,對(duì)端待連接的 PA 需要實(shí)現(xiàn)對(duì)應(yīng)的客戶端,代碼示例如下所示:

// 以計(jì)算加法為例,對(duì)端實(shí)現(xiàn)的客戶端如下
   public class MyRemote extends RemoteObject implements IRemoteBroker{
       private static final int ERR_OK = 0;
       private static final int ERROR = -1;
       private static final int COMMAND_PLUS = IRemoteObject.MIN_TRANSACTION_ID;
    
       public MyRemote() {
           super("MyService_Remote");
       }
    
       @Override
       public IRemoteObject asObject() {
           return this;
       }
    
       @Override
       public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
           if (code != COMMAND_PLUS) {
               reply.writeInt(ERROR);
               return false;
           }
           int value1 = data.readInt();
           int value2 = data.readInt();
           int sum = value1 + value2;
           reply.writeInt(ERR_OK);
           reply.writeInt(sum);
           return true;
       }
   }
   }
}

對(duì)端除了要實(shí)現(xiàn)如上所述的客戶端外,待連接的 PA 還需要作如下修改:

// 為了返回給連接方可調(diào)用的代理,需要在該 PA 中實(shí)例化客戶端,例如作為該 PA 的成員變量
   private MyProxy remote = new MyProxy();
   // 當(dāng)該 PA 接收到連接請(qǐng)求時(shí),即將該客戶端轉(zhuǎn)化為代理返回給連接發(fā)起側(cè)
   @Override
   protected IRemoteObject onConnect(Intent intent) {
       super.onConnect(intent);
       return remote.asObject();
   }
   }
}

完成上述步驟后,可以通過(guò)點(diǎn)擊事件實(shí)現(xiàn)連接、利用連接關(guān)系控制 PA 以及斷開(kāi)連接等行為,代碼示例如下:

// 連接遠(yuǎn)程PA
   private ClickedListener mConnectRemotePAListener = new ClickedListener() {
       @Override
       public void onClick(Component arg0) {
           scheduleRemoteAbility(new ISelectResult() {
               @Override
               void onSelectResult(String deviceId) {
                   if (deviceId != null) {
                       Intent connectPAIntent = new Intent();
                       // bundleName和abilityName與待連接的PA一一對(duì)應(yīng)
                       // 例如:bundleName = "com.huawei.helloworld"
                       //       abilityName = "com.huawei.helloworld.SampleParticleAbility"
                       Operation operation = new Intent.OperationBuilder()
                               .withDeviceId(deviceId)
                               .withBundleName(bundleName)
                               .withAbilityName(abilityName)
                               .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                               .build();
                       connectPAIntent.setOperation(operation);
                       connectAbility(connectPAIntent, conn);
                   }
               }
           });
       }
   };
   // 控制已連接PA執(zhí)行加法
   private ClickedListener mControlPAListener = new ClickedListener() {
       @Override
       public void onClick(Component arg0) {
           if (mProxy != null) {
               int ret = -1;
               try {
                   ret = mProxy.plus(10, 20);
               } catch (RemoteException e) {
                   e.printStackTrace();
               }
               btnControlRemotePA.setText("ControlRemotePA result = " + ret);
           }
       }
   };
   // 與遠(yuǎn)程PA斷開(kāi)連接
   private ClickedListener mDisconnectRemotePAListener = new ClickedListener() {
       @Override
       public void onClick(Component arg0) {
           // 按鈕復(fù)位
           btnConnectRemotePA.setText("ConnectRemotePA");
           btnControlRemotePA.setText("ControlRemotePA");
           disconnectAbility(conn);
       }
   };
   };
};

說(shuō)明

通過(guò)連接/斷開(kāi)連接遠(yuǎn)程 PA,與跨設(shè)備 PA 建立長(zhǎng)期的管理關(guān)系。例如在本例中,通過(guò)連接關(guān)系得到遠(yuǎn)程 PA 的控制代理后,實(shí)現(xiàn)跨設(shè)備計(jì)算加法并將結(jié)果返回到本地顯示。在實(shí)際開(kāi)發(fā)中,開(kāi)發(fā)者可以根據(jù)需要實(shí)現(xiàn)多種分布式場(chǎng)景,例如:跨設(shè)備位置/電量等信息的采集、跨設(shè)備計(jì)算資源互助等。

  • 設(shè)備 A 將運(yùn)行時(shí)的 FA 遷移到設(shè)備 B,實(shí)現(xiàn)業(yè)務(wù)在設(shè)備間無(wú)縫遷移。
// 跨設(shè)備遷移FA
   // 本地FA設(shè)置當(dāng)前運(yùn)行任務(wù)
   private ClickedListener mContinueAbilityListener = new ClickedListener() {
       @Override
       public void onClick(Component arg0) {
           // 用戶選擇設(shè)備后實(shí)現(xiàn)業(yè)務(wù)遷移
           scheduleRemoteAbility(new ISelectResult() {
               @Override
               public void onSelectResult(String deviceId) {
                   continueAbility(deviceId);
               }
           });
       }
   };
   };
};

此外,不同于啟動(dòng)行為,F(xiàn)A 的遷移還涉及到狀態(tài)數(shù)據(jù)的傳遞。為此,繼承的 IAbilityContinuation 接口為開(kāi)發(fā)者提供遷移過(guò)程中特定事件的管理能力。通過(guò)自定義遷移事件相關(guān)的行為,最終實(shí)現(xiàn)對(duì) Ability 的遷移。具體的定義可以參考相關(guān)的 API 文檔,此處主要以較為常用的兩個(gè)事件,包括遷移發(fā)起端完成遷移的回調(diào) onCompleteContinuation(int result)以及接收到遠(yuǎn)端遷移行為傳遞數(shù)據(jù)的回調(diào) onRestoreData(IntentParams restoreData)。其他還包括遷移到遠(yuǎn)端設(shè)備的 FA 關(guān)閉的回調(diào) onRemoteTerminated()、用于本地遷移發(fā)起時(shí)保存狀態(tài)數(shù)據(jù)的回調(diào) onSaveData(IntentParams saveData)和本地發(fā)起遷移的回調(diào) onStartContinuation()。按照實(shí)際應(yīng)用自定義特定場(chǎng)景對(duì)應(yīng)的回調(diào),可以完成多種場(chǎng)景下 FA 的遷移任務(wù)。

@Override
   public boolean onSaveData(IntentParams saveData) {
       String exampleData = String.valueOf(System.currentTimeMillis());
       saveData.setParam("continueParam", exampleData);
       return true;
   }
    
   @Override
   public boolean onRestoreData(IntentParams restoreData) {
       // 遠(yuǎn)端FA遷移傳來(lái)的狀態(tài)數(shù)據(jù),開(kāi)發(fā)者可以按照特定的場(chǎng)景對(duì)這些數(shù)據(jù)進(jìn)行處理
       Object data = restoreData.getParam("continueParam");
       return true;
   }
    
   @Override
   public void onCompleteContinuation(int result) {
       btnContinueRemoteFA.setText("ContinueAbility Done");
   }
   }
}

說(shuō)明

1.FA 遷移可以打通設(shè)備間的壁壘,有助于不同能力的設(shè)備進(jìn)行互助。前文以一個(gè)簡(jiǎn)單的例子介紹如何通過(guò)分布式任務(wù)調(diào)度提供的能力,實(shí)現(xiàn) FA 跨設(shè)備的遷移(包括 FA 啟動(dòng)及狀態(tài)數(shù)據(jù)的同步)。 2.FA 遷移過(guò)程中,遠(yuǎn)端 FA 首先接收到發(fā)起端 FA 傳輸?shù)臄?shù)據(jù),再執(zhí)行啟動(dòng),即 onRestoreData() 發(fā)生在 onStart() 之前。

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 分布式
    +關(guān)注

    關(guān)注

    1

    文章

    997

    瀏覽量

    75413
  • 鴻蒙
    +關(guān)注

    關(guān)注

    60

    文章

    2620

    瀏覽量

    44063
  • OpenHarmony
    +關(guān)注

    關(guān)注

    29

    文章

    3854

    瀏覽量

    18628
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Ceph分布式存儲(chǔ)系統(tǒng)解析

    在當(dāng)今數(shù)據(jù)爆炸的時(shí)代,企業(yè)對(duì)存儲(chǔ)系統(tǒng)的需求日益增長(zhǎng),傳統(tǒng)的集中式存儲(chǔ)已經(jīng)無(wú)法滿足大規(guī)模數(shù)據(jù)處理的要求。分布式存儲(chǔ)系統(tǒng)應(yīng)運(yùn)而生,而Ceph作為開(kāi)源分布式存儲(chǔ)系統(tǒng)的佼佼者,以其高可用性、高擴(kuò)展性和統(tǒng)一存儲(chǔ)架構(gòu)贏得了眾多企業(yè)的青睞。
    的頭像 發(fā)表于 07-14 11:15 ?173次閱讀

    鴻蒙5開(kāi)發(fā)寶藏案例分享---應(yīng)用并發(fā)設(shè)計(jì)

    一句 : 鴻蒙的并發(fā)模型是為分布式而生的設(shè)計(jì),吃透這些案例后你會(huì)發(fā)現(xiàn): 折疊屏/多端適配不再頭疼 性能調(diào)優(yōu)有跡可循 復(fù)雜業(yè)務(wù)邏輯清晰解耦 遇到坑點(diǎn)歡迎回聊討論~ 覺(jué)得有用記得點(diǎn)贊收藏?
    發(fā)表于 06-12 16:19

    分布式IO模組選購(gòu)指南:2025主流品牌盤(pán)點(diǎn)與應(yīng)用方案解析

    ,分布式IO模塊市場(chǎng)進(jìn)入快速增長(zhǎng)期。本文基于權(quán)威數(shù)據(jù)平臺(tái)的市場(chǎng)分析,盤(pán)點(diǎn)2025年主流分布式IO模塊品牌,介紹優(yōu)勢(shì)產(chǎn)品,并解析典型應(yīng)用方案,旨在為企業(yè)選購(gòu)提供權(quán)威參考。
    的頭像 發(fā)表于 06-10 16:57 ?256次閱讀

    輸電線路分布式故障定位裝置的原理、優(yōu)勢(shì)與應(yīng)用場(chǎng)景解析

    輸電線路分布式故障定位裝置的原理、優(yōu)勢(shì)與應(yīng)用場(chǎng)景解析
    的頭像 發(fā)表于 05-16 09:25 ?220次閱讀

    使用VirtualLab Fusion中分布式計(jì)算的AR波導(dǎo)測(cè)試圖像模擬

    總計(jì)算時(shí)間超過(guò)31小時(shí)。通過(guò)使用一個(gè)由8個(gè)多核PC組成的網(wǎng)絡(luò),提供35個(gè)客戶端分布式計(jì)算,將模擬時(shí)間減少到1小時(shí)5分鐘?;灸M任務(wù)基本任務(wù)集合:FOV使用分布式計(jì)算的集合模擬概述模擬
    發(fā)表于 04-10 08:48

    【「鴻蒙操作系統(tǒng)設(shè)計(jì)原理與架構(gòu)」閱讀體驗(yàn)】02-華為鴻蒙設(shè)計(jì)理念

    用戶帶來(lái)了極大的便利 。 這種智能的任務(wù)分配和遷移機(jī)制,不僅提高了用戶體驗(yàn),還充分發(fā)揮了不同設(shè)備的優(yōu)勢(shì),實(shí)現(xiàn)了資源的優(yōu)化利用 。在分布式任務(wù)調(diào)度的支持下,
    發(fā)表于 02-23 16:16

    VirtualLab Fusion應(yīng)用:基于分布式計(jì)算的AR光波導(dǎo)中測(cè)試圖像的仿真

    (10201次模擬):大約43小時(shí)。 模擬結(jié)果:不同視場(chǎng)角的輻射通量*。 *注: 21個(gè)×21個(gè)方向的結(jié)果存儲(chǔ)在參數(shù)連續(xù)變化的光柵的查找表中。 使用分布式計(jì)算 參數(shù)運(yùn)行用于改變當(dāng)前視場(chǎng)模式的角度,這
    發(fā)表于 02-19 08:51

    分布式云化數(shù)據(jù)庫(kù)有哪些類(lèi)型

    分布式云化數(shù)據(jù)庫(kù)有哪些類(lèi)型?分布式云化數(shù)據(jù)庫(kù)主要類(lèi)型包括:關(guān)系型分布式數(shù)據(jù)庫(kù)、非關(guān)系型分布式數(shù)據(jù)庫(kù)、新SQL分布式數(shù)據(jù)庫(kù)、以列方式存儲(chǔ)數(shù)據(jù)、
    的頭像 發(fā)表于 01-15 09:43 ?482次閱讀

    AIGC入門(mén)及鴻蒙入門(mén)

    JDK、配置SDK等。 3. 開(kāi)發(fā)實(shí)踐: 學(xué)習(xí)鴻蒙系統(tǒng)的架構(gòu)和API,了解其組件化、分布式等特性。 通過(guò)官方文檔和社區(qū)資源,學(xué)習(xí)和掌握鴻蒙應(yīng)用的開(kāi)發(fā)
    發(fā)表于 01-13 10:32

    HarmonyOS Next 應(yīng)用元服務(wù)開(kāi)發(fā)-分布式數(shù)據(jù)對(duì)象遷移數(shù)據(jù)文件資產(chǎn)遷移

    設(shè)備文件訪問(wèn)實(shí)現(xiàn)文件的遷移,難以獲取文件同步完成的時(shí)間。為了保證更高的成功率,文件的遷移不建議繼續(xù)通過(guò)該方式實(shí)現(xiàn),推薦使用分布式數(shù)據(jù)對(duì)象攜帶資產(chǎn)的方式。開(kāi)發(fā)者此前通過(guò)跨設(shè)備文件訪問(wèn)實(shí)現(xiàn)的文件遷移依然生效
    發(fā)表于 12-24 10:11

    HarmonyOS Next 應(yīng)用元服務(wù)開(kāi)發(fā)-分布式數(shù)據(jù)對(duì)象遷移數(shù)據(jù)權(quán)限與基礎(chǔ)數(shù)據(jù)

    設(shè)備文件訪問(wèn)實(shí)現(xiàn)文件的遷移,難以獲取文件同步完成的時(shí)間。為了保證更高的成功率,文件的遷移不建議繼續(xù)通過(guò)該方式實(shí)現(xiàn),推薦使用分布式數(shù)據(jù)對(duì)象攜帶資產(chǎn)的方式。開(kāi)發(fā)者此前通過(guò)跨設(shè)備文件訪問(wèn)實(shí)現(xiàn)的文件遷移依然生效
    發(fā)表于 12-24 09:40

    名單公布!【書(shū)籍評(píng)測(cè)活動(dòng)NO.53】鴻蒙操作系統(tǒng)設(shè)計(jì)原理與架構(gòu)

    的底層設(shè)計(jì)邏輯出發(fā),針對(duì)不同關(guān)鍵子系統(tǒng)的目標(biāo)功能和實(shí)現(xiàn)路徑做實(shí)際分析解讀,幫助開(kāi)發(fā)者理解鴻蒙操作系統(tǒng)的底層邏輯,開(kāi)發(fā)更適合系統(tǒng)邏輯的架構(gòu)代碼。 以分布式軟總線原理
    發(fā)表于 12-16 15:10

    分布式光伏為企業(yè)帶來(lái)哪些便捷!

    光伏開(kāi)發(fā)試點(diǎn)方案的通知》中指出:“為加快推進(jìn)屋頂分布式光伏發(fā)展,擬在全國(guó)組織開(kāi)展整縣(市、區(qū))推進(jìn)屋頂分布式光伏開(kāi)發(fā)試點(diǎn)工作”? 一,行業(yè)痛點(diǎn): 1,監(jiān)管困難:
    的頭像 發(fā)表于 11-18 15:34 ?739次閱讀
    <b class='flag-5'>分布式</b>光伏為企業(yè)帶來(lái)哪些便捷!

    分布式光纖測(cè)溫解決方案

    分布式光纖測(cè)溫解決方案
    的頭像 發(fā)表于 11-12 01:02 ?565次閱讀
    <b class='flag-5'>分布式</b>光纖測(cè)溫解決方案

    基于分布式計(jì)算的AR光波導(dǎo)中測(cè)試圖像的仿真

    (10201次模擬):大約43小時(shí)。 模擬結(jié)果:不同視場(chǎng)角的輻射通量。 注: 21個(gè)×21個(gè)方向的結(jié)果存儲(chǔ)在參數(shù)連續(xù)變化的光柵的查找表中。 使用分布式計(jì)算 參數(shù)運(yùn)行用于改變當(dāng)前視場(chǎng)模式的角度,這允許將
    發(fā)表于 08-07 14:13