鸿蒙OS 发布式任务调度开发指导

2020-09-18 11:00 更新

场景介绍

开发者在应用中集成分布式调度能力,通过调用指定能力的分布式接口,实现跨设备能力调度。根据 Ability 模板及意图的不同,分布式任务调度向开发者提供以下六种能力:启动远程 FA、启动远程 PA、关闭远程 PA、连接远程 PA、断开连接远程 PA 和 FA 跨设备迁移。下面以设备 A(本地设备)和设备 B(远端设备)为例,进行场景介绍:

  1. 设备 A 启动设备 B 的 FA:在设备 A 上通过本地应用提供的启动按钮,启动设备 B 上对应的 FA。例如:设备 A 控制设备 B 打开相册,只需开发者在启动 FA 时指定打开相册的意图即可。
  2. 设备 A 启动设备 B 的 PA:在设备 A 上通过本地应用提供的启动按钮,启动设备 B 上指定的 PA。例如:开发者在启动远程服务时通过意图指定音乐播放服务,即可实现设备 A 启动设备 B 音乐播放的能力。
  3. 设备 A 关闭设备 B 的 PA:在设备 A 上通过本地应用提供的关闭按钮,关闭设备 B 上指定的 PA。类似启动的过程,开发者在关闭远程服务时通过意图指定音乐播放服务,即可实现关闭设备 B 上该服务的能力。
  4. 设备 A 连接设备 B 的 PA:在设备 A 上通过本地应用提供的连接按钮,连接设备 B 上指定的 PA。连接后,通过其他功能相关按钮实现控制对端 PA 的能力。通过连接关系,开发者可以实现跨设备的同步服务调度,实现如大型计算任务互助等价值场景。
  5. 设备 A 与设备 B 的 PA 断开连接:在设备 A 上通过本地应用提供断开连接的按钮,将之前已连接的 PA 断开连接。
  6. 设备 A 的 FA 迁移至设备B:设备 A 上通过本地应用提供的迁移按钮,将设备 A 的业务无缝迁移到设备B中。通过业务迁移能力,打通设备 A 和设备 B 间的壁垒,实现如文档跨设备编辑、视频从客厅到房间跨设备接续播放等场景。

接口说明

分布式调度平台提供的连接和断开连接 PA、启动远程 FA、启动和关闭 PA 以及迁移 FA 的能力,是实现更多价值性场景的基础。

连接远程PA

connectAbility(Intent intent, IAbilityConnection conn)接口提供连接指定设备上 PA 的能力,Intent 中指定待连接 PA 的设备 deviceId、bundleName 和 abilityName。当连接成功后,通过在 conn 定义的 onAbilityConnectDone 回调中获取对端 PA 的服务代理,两者的连接关系则由 conn 维护。具体的参数定义如下表所示:

参数名 类型 说明
intent ohos.aafwk.content.Intent 开发者需在 intent 对应的Operation 中指定待连接 PA 的设备 deviceId、bundleName 和 abilityName。
conn ohos.aafwk.ability.IAbilityConnection 当连接成功或失败时,作为连接关系的回调接口。该接口提供连接完成和断开连接完成时的处理逻辑,开发者可根据具体的场景进行定义。

启动远程FA/PA

startAbility(Intent intent) 接口提供启动指定设备上 FA 和 PA 的能力,Intent 中指定待启动 FA/PA 的设备 deviceId、bundleName 和 abilityName。具体参数定义如下表所示:

参数名 类型 说明
intent ohos.aafwk.content.Intent 当开发者需要调用该接口启动远程 PA 时,需要指定待启动 PA 的设备 deviceId、bundleName 和 abilityName。若不指定设备deviceId,则无法跨设备调用 PA。类似地,在启动FA时,也需要开发者指定启动 FA 的设备 deviceId、bundleName 和 abilityName。

分布式调度平台还会提供与上述功能相对应的断开远程 PA 的连接和关闭远程 PA 的接口,相关的参数与连接、启动的接口类似。

  • 断开远程 PA 连接:disconnectAbility (IAbilityConnection conn)。
  • 关闭远程 PA:boolean stopAbility (Intent intent)。

迁移FA

continueAbility(String deviceId)接口提供将本地FA迁移到指定设备上的能力,需要开发者在调用时指定目标设备的 deviceId。具体参数定义如下表所示:

说明

Ability 和 AbilitySlice 类均需要实现 IAbilityContinuation 及其方法,才可以实现 FA 迁移。

参数名 类型 说明
deviceId String 当开发者需要调用该接口将本地 FA 迁移时,需要指定目标设备的 deviceId。

开发步骤

  1. 导入功能依赖的包。

  1. // 以下依赖包含分布式调度平台开放的接口,用于:连接/断开连接远程 PA、启动远程 FA、通过连接关系注册的回调函数 onAbilityConnectDon e中返回的对端 PA 的代理,实现对PA的控制
  2. import ohos.aafwk.ability.AbilitySlice;
  3. import ohos.aafwk.ability.IAbilityConnection;
  4. import ohos.aafwk.content.Intent;
  5. import ohos.aafwk.content.Operation;
  6. import ohos.bundle.ElementName;
  7. // 为了实现迁移能力,需要引入传递迁移所需数据的包以及实现迁移能力的接口。
  8. import ohos.aafwk.ability.IAbilityContinuation;
  9. import ohos.aafwk.content.IntentParams;
  10. // 为了实现跨设备指令及数据通信,需要集成 HarmonyOS 提供的 RPC 接口
  11. import ohos.rpc.IRemoteObject;
  12. import ohos.rpc.IRemoteBroker;
  13. import ohos.rpc.MessageParcel;
  14. import ohos.rpc.MessageOption;
  15. import ohos.rpc.RemoteException;
  16. import ohos.rpc.RemoteObject;
  17. //(可选)多设备场景下涉及设备选择,为此需要引入组网设备发现的能力
  18. import ohos.distributedschedule.interwork.DeviceInfo;
  19. import ohos.distributedschedule.interwork.DeviceManager;
  20. // (可选)设计界面相关的包函数,对 FA 界面及按钮进行绘制
  21. import ohos.agp.components.Button;
  22. import ohos.agp.components.Component;
  23. import ohos.agp.components.Component.ClickedListener;
  24. import ohos.agp.components.ComponentContainer.LayoutConfig;
  25. import ohos.agp.components.element.ShapeElement;
  26. import ohos.agp.components.PositionLayout;

  1. (可选)编写一个基本的 FA 用于使用分布式能力。

  1. // 调用 AbilitySlice 模板实现一个用于控制基础功能的 FA
  2. // Ability 和 AbilitySlice 类均需要实现 IAbilityContinuation 及其方法,才可以实现 FA 迁移。AbilitySlice 的代码示例如下
  3. public class SampleSlice extends AbilitySlice implements IAbilityContinuation {
  4. @Override
  5. public void onStart(Intent intent) {
  6. super.onStart(intent);
  7. // 开发者可以自行进行界面设计
  8. // 为按钮设置统一的背景色
  9. // 例如通过PositionLayout指定大小可以实现简单界面
  10. PositionLayout layout = new PositionLayout(this);
  11. LayoutConfig config = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT);
  12. layout.setLayoutConfig(config);
  13. ShapeElement buttonBg = new ShapeElement();
  14. buttonBg.setRgbColor(new RgbColor(0,125,255));
  15. addComponents(layout, buttonBg, config);
  16. super.setUIContent(layout);
  17. }
  18. @Override
  19. public void onInactive() {
  20. super.onInactive();
  21. }
  22. @Override
  23. public void onActive() {
  24. super.onActive();
  25. }
  26. @Override
  27. public void onBackground() {
  28. super.onBackground();
  29. }
  30. @Override
  31. public void onForeground(Intent intent) {
  32. super.onForeground(intent);
  33. }
  34. @Override
  35. public void onStop() {
  36. super.onStop();
  37. }
  38. }

说明

此步骤展示了一个简单 FA 的实现过程,实际开发中请开发者根据需要进行设计。

  1. (可选)为不同的能力设置相应的控制按钮。

  1. // 建议开发者按照自己的界面进行按钮设计
  2. // 开发者可以自行实现如 createButton 的方法,新建一个显示文字 text,背景色为 buttonBg 以及大小尺寸位置符合 config 设置的按钮,用来与用户发生交互
  3. // private Button createButton(String text, ShapeElement buttonBg, LayoutConfig config)
  4. // 按照顺序在 PositionLayout 中依次添加按钮的示例
  5. private void addComponents(PositionLayout linear, ShapeElement buttonBg, LayoutConfig config) {
  6. // 构建远程启动FA的按钮
  7. btnStartRemoteFA = createButton("StartRemoteFA", buttonBg, config);
  8. btnStartRemoteFA.setClickedListener(mStartRemoteFAListener);
  9. linear.addComponent(btnStartRemoteFA);
  10. // 构建远程启动PA的按钮
  11. btnStartRemotePA = createButton("StartRemotePA", buttonBg, config);
  12. btnStartRemotePA.setClickedListener(mStartRemotePAListener);
  13. linear.addComponent(btnStartRemotePA);
  14. // 构建远程关闭PA的按钮
  15. btnStopRemotePA = createButton("StopRemotePA", buttonBg, config);
  16. btnStopRemotePA.setClickedListener(mStopRemotePAListener);
  17. linear.addComponent(btnStopRemotePA);
  18. // 构建连接远程PA的按钮
  19. btnConnectRemotePA = createButton("ConnectRemotePA", buttonBg, config);
  20. btnConnectRemotePA.setClickedListener(mConnectRemotePAListener);
  21. linear.addComponent(btnConnectRemotePA);
  22. // 构建控制连接PA的按钮
  23. btnControlRemotePA = createButton("ControlRemotePA", buttonBg, config);
  24. btnControlRemotePA.setClickedListener(mControlPAListener);
  25. linear.addComponent(btnControlRemotePA);
  26. // 构建与远程PA断开连接的按钮
  27. btnDisconnectRemotePA = createButton("DisconnectRemotePA", buttonBg, config);
  28. btnDisconnectRemotePA.setClickedListener(mDisconnectRemotePAListener);
  29. linear.addComponent(btnDisconnectRemotePA);
  30. // 构建迁移FA的按钮
  31. btnContinueRemoteFA = createButton("ContinueRemoteFA", buttonBg, config);
  32. btnContinueRemoteFA.setClickedListener(mContinueAbilityListener);
  33. linear.addComponent(btnContinueRemoteFA);
  34. }

说明

此处只展示了基于按钮控制的能力调度方法,实际开发中请开发者根据需要选择能力调度方式。代码示例中未体现按钮如位置、样式等具体的设置方法,详请参考 JAVA UI框架

  1. 通过设备管理 DeviceManager 提供的 getDeviceList 接口获取设备列表,用于指定目标设备。

  1. // ISelectResult 是一个自定义接口,用来处理指定设备 deviceId 后执行的行为
  2. interface ISelectResult {
  3. void onSelectResult(String deviceId);
  4. }
  5. // 获得设备列表,开发者可在得到的在线设备列表中选择目标设备执行操作
  6. private void scheduleRemoteAbility(ISelectResult listener) {
  7. // 调用DeviceManager的getDeviceList接口,通过FLAG_GET_ONLINE_DEVICE标记获得在线设备列表
  8. List<DeviceInfo> onlineDevices = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
  9. // 判断组网设备是否为空
  10. if (onlineDevices.isEmpty()) {
  11. listener.onSelectResult(null);
  12. return;
  13. }
  14. int numDevices = onlineDevices.size();
  15. ArrayList<String> deviceIds = new ArrayList<>(numDevices);
  16. ArrayList<String> deviceNames = new ArrayList<>(numDevices);
  17. onlineDevices.forEach((device) -> {
  18. deviceIds.add(device.getDeviceId());
  19. deviceNames.add(device.getDeviceName());
  20. });
  21. // 以选择首个设备作为目标设备为例
  22. // 开发者也可按照具体场景,通过别的方式进行设备选择
  23. String selectDeviceId = deviceIds.get(0);
  24. listener.onSelectResult(selectDeviceId);
  25. }

上述实例中涉及对在线组网设备的查询,该项能力需要开发者在对应的 config.json 中声明获取设备列表及设备信息的权限,如下所示:

  1. {
  2. "reqPermissions": [
  3. {
  4. "name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
  5. },
  6. {
  7. "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
  8. },
  9. {
  10. "name": "ohos.permission.GET_BUNDLE_INFO"
  11. }
  12. ]
  13. }

  1. 为启动远程 FA 的按钮设置点击回调,实现启动远程 FA 的能力。

  1. // 启动一个指定 bundleName 和 abilityName 的 FA
  2. private ClickedListener mStartRemoteFAListener = new ClickedListener() {
  3. @Override
  4. public void onClick(Component arg0) {
  5. // 启动远程PA
  6. scheduleRemoteAbility(new ISelectResult() {
  7. @Override
  8. void onSelectResult(String deviceId) {
  9. if (deviceId != null) {
  10. Intent intent = new Intent();
  11. // 通过scheduleRemoteAbility指定目标设备deviceId
  12. // 指定待启动FA的bundleName和abilityName
  13. // 例如:bundleName = "com.huawei.helloworld"
  14. // abilityName = "com.huawei.helloworld.SampleFeatureAbility"
  15. // 设置分布式标记,表明当前涉及分布式能力
  16. Operation operation = new Intent.OperationBuilder()
  17. .withDeviceId(deviceId)
  18. .withBundleName(bundleName)
  19. .withAbilityName(abilityName)
  20. .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
  21. .build();
  22. intent.setOperation(operation);
  23. // 通过AbilitySlice包含的startAbility接口实现跨设备启动FA
  24. startAbility(intent);
  25. }
  26. }
  27. });
  28. }
  29. };

  1. 为启动和关闭 PA 定义回调,实现启动和关闭 PA 的能力。

对于 PA 的启动、关闭、连接等操作都需要开发者提供目标设备的 deviceId。开发者可以通过 DeviceManager 相关接口得到当前组网下的设备列表,并以弹窗的形式供用户选择,也可以按照实际需要实现其他个性化的处理方式。在点击事件回调函数中,需要开发者指定得到 deviceId 后的处理逻辑,即实现类似上例中 listener.onSelectResult(String deviceId) 的方法,代码示例如下:

  1. // 启动远程 PA
  2. private ClickedListener mStartRemotePAListener = new ClickedListener() {
  3. @Override
  4. public void onClick(Component arg0) {
  5. // 启动远程PA
  6. scheduleRemoteAbility(new ISelectResult() {
  7. @Override
  8. void onSelectResult(String deviceId) {
  9. if (deviceId != null) {
  10. Intent intentToStartPA = new Intent();
  11. // bundleName和abilityName与待启动PA对应
  12. // 例如:bundleName = "com.huawei.helloworld"
  13. // abilityName = "com.huawei.helloworld.SampleParticleAbility"
  14. Operation operation = new Intent.OperationBuilder()
  15. .withDeviceId(deviceId)
  16. .withBundleName(bundleName)
  17. .withAbilityName(abilityName)
  18. .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
  19. .build();
  20. intentToStartPA.setOperation(operation);
  21. startAbility(intentToStartPA);
  22. }
  23. }
  24. });
  25. }
  26. };
  27. // 关闭远程 PA,和启动类似开发者需要指定待关闭 PA 对应的 bundleName 和 abilityName
  28. private ClickedListener mStopRemotePAListener = new ClickedListener() {
  29. @Override
  30. public void onClick(Component arg0) {
  31. scheduleRemoteAbility(new ISelectResult() {
  32. @Override
  33. void onSelectResult(String deviceId) {
  34. if (deviceId != null) {
  35. Intent intentToStopPA = new Intent();
  36. // bundleName和abilityName与待关闭PA对应
  37. // 例如:bundleName = "com.huawei.helloworld"
  38. // abilityName = "com.huawei.helloworld.SampleParticleAbility"
  39. Operation operation = new Intent.OperationBuilder()
  40. .withDeviceId(deviceId)
  41. .withBundleName(bundleName)
  42. .withAbilityName(abilityName)
  43. .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
  44. .build();
  45. intentToStopPA.setOperation(operation);
  46. stopAbility(intentToStopPA);
  47. }
  48. }
  49. });
  50. }
  51. };

说明

启动和关闭的行为类似,开发者只需在 Intent 中指定待调度 PA 的 deviceId、bundleName 和 abilityName,并以 operation 的形式封装到 Intent 内。通过 AbilitySlice(Ability)包含的 startAbility()和 stopAbility()接口即可实现相应功能。

  1. 设备 A 连接设备 B 侧的 PA,利用连接关系调用该 PA 执行特定任务,以及断开连接。

  1. // 当连接完成时,用来提供管理已连接 PA 的能力
  2. private MyRemoteProxy mProxy = null;
  3. // 用于管理连接关系
  4. private IAbilityConnection conn = new IAbilityConnection() {
  5. @Override
  6. public void onAbilityConnectDone(ElementName element, IRemoteObject remote, int resultCode) {
  7. // 跨设备PA连接完成后,会返回一个序列化的IRemoteObject对象
  8. // 通过该对象得到控制远端服务的代理
  9. mProxy = new MyRemoteProxy(remote);
  10. btnConnectRemotePA.setText("connectRemoteAbility done");
  11. }
  12. @Override
  13. public void onAbilityDisconnectDone(ElementName element, int resultCode) {
  14. // 当已连接的远端PA关闭时,会触发该回调
  15. // 支持开发者按照返回的错误信息进行PA生命周期管理
  16. disconnectAbility(conn);
  17. }
  18. };

仅通过启动/关闭两种方式对 PA 进行调度无法应对需长期交互的场景,因此,分布式任务调度平台向开发者提供了跨设备PA连接及断开连接的能力。为了对已连接 PA 进行管理,开发者需要实现一个满足 IAbilityConnection 接口的连接状态检测实例,通过该实例可以对连接及断开连接完成时设置具体的处理逻辑,例如:获取控制对端 PA 的代理等。进一步为了使用该代理跨设备调度 PA,开发者需要在本地及对端分别实现对外接口一致的代理。一个具备加法能力的代理示例如下:

  1. // 以连接提供加法计算能力的 PA 为例。为了提供跨设备连接能力,需要在本地发起连接侧和对端被连接侧分别实现代理。
  2. // 发起连接侧的代理示例如下
  3. public class MyRemoteProxy implements IRemoteBroker{
  4. private static final int ERR_OK = 0;
  5. private static final int COMMAND_PLUS = IRemoteObject.MIN_TRANSACTION_ID;
  6. private final IRemoteObject remote;
  7. public MyRemoteProxy(
  8. /* [in] */ IRemoteObject remote) {
  9. this.remote = remote;
  10. }
  11. @Override
  12. public IRemoteObject asObject() {
  13. return remote;
  14. }
  15. public int plus(
  16. /* [in] */ int a,
  17. /* [in] */ int b) throws RemoteException {
  18. MessageParcel data = MessageParcel.obtain();
  19. MessageParcel reply = MessageParcel.obtain();
  20. // option不同的取值,决定采用同步或异步方式跨设备控制PA
  21. // 本例需要同步获取对端PA执行加法的结果,因此采用同步的方式,即MessageOption.TF_SYNC
  22. // 具体MessageOption的设置,可参考相关API文档
  23. MessageOption option = new MessageOption(MessageOption.TF_SYNC);
  24. data.writeInt(a);
  25. data.writeInt(b);
  26. try {
  27. remote.sendRequest(COMMAND_PLUS, data, reply, option);
  28. int ec = reply.readInt();
  29. if (ec != ERR_OK) {
  30. throw new RemoteException();
  31. }
  32. int result = reply.readInt();
  33. return result;
  34. } catch (RemoteException e) {
  35. throw new RemoteException();
  36. } finally {
  37. data.reclaim();
  38. reply.reclaim();
  39. }
  40. }
  41. }

此外,对端待连接的 PA 需要实现对应的客户端,代码示例如下所示:

  1. // 以计算加法为例,对端实现的客户端如下
  2. public class MyRemote extends RemoteObject implements IRemoteBroker{
  3. private static final int ERR_OK = 0;
  4. private static final int ERROR = -1;
  5. private static final int COMMAND_PLUS = IRemoteObject.MIN_TRANSACTION_ID;
  6. public MyRemote() {
  7. super("MyService_Remote");
  8. }
  9. @Override
  10. public IRemoteObject asObject() {
  11. return this;
  12. }
  13. @Override
  14. public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
  15. if (code != COMMAND_PLUS) {
  16. reply.writeInt(ERROR);
  17. return false;
  18. }
  19. int value1 = data.readInt();
  20. int value2 = data.readInt();
  21. int sum = value1 + value2;
  22. reply.writeInt(ERR_OK);
  23. reply.writeInt(sum);
  24. return true;
  25. }
  26. }

对端除了要实现如上所述的客户端外,待连接的 PA 还需要作如下修改:

  1. // 为了返回给连接方可调用的代理,需要在该 PA 中实例化客户端,例如作为该 PA 的成员变量
  2. private MyProxy remote = new MyProxy();
  3. // 当该 PA 接收到连接请求时,即将该客户端转化为代理返回给连接发起侧
  4. @Override
  5. protected IRemoteObject onConnect(Intent intent) {
  6. super.onConnect(intent);
  7. return remote.asObject();
  8. }

完成上述步骤后,可以通过点击事件实现连接、利用连接关系控制 PA 以及断开连接等行为,代码示例如下:

  1. // 连接远程PA
  2. private ClickedListener mConnectRemotePAListener = new ClickedListener() {
  3. @Override
  4. public void onClick(Component arg0) {
  5. scheduleRemoteAbility(new ISelectResult() {
  6. @Override
  7. void onSelectResult(String deviceId) {
  8. if (deviceId != null) {
  9. Intent connectPAIntent = new Intent();
  10. // bundleName和abilityName与待连接的PA一一对应
  11. // 例如:bundleName = "com.huawei.helloworld"
  12. // abilityName = "com.huawei.helloworld.SampleParticleAbility"
  13. Operation operation = new Intent.OperationBuilder()
  14. .withDeviceId(deviceId)
  15. .withBundleName(bundleName)
  16. .withAbilityName(abilityName)
  17. .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
  18. .build();
  19. connectPAIntent.setOperation(operation);
  20. connectAbility(connectPAIntent, conn);
  21. }
  22. }
  23. });
  24. }
  25. };
  26. // 控制已连接PA执行加法
  27. private ClickedListener mControlPAListener = new ClickedListener() {
  28. @Override
  29. public void onClick(Component arg0) {
  30. if (mProxy != null) {
  31. int ret = -1;
  32. try {
  33. ret = mProxy.plus(10, 20);
  34. } catch (RemoteException e) {
  35. e.printStackTrace();
  36. }
  37. btnControlRemotePA.setText("ControlRemotePA result = " + ret);
  38. }
  39. }
  40. };
  41. // 与远程PA断开连接
  42. private ClickedListener mDisconnectRemotePAListener = new ClickedListener() {
  43. @Override
  44. public void onClick(Component arg0) {
  45. // 按钮复位
  46. btnConnectRemotePA.setText("ConnectRemotePA");
  47. btnControlRemotePA.setText("ControlRemotePA");
  48. disconnectAbility(conn);
  49. }
  50. };

说明

通过连接/断开连接远程 PA,与跨设备 PA 建立长期的管理关系。例如在本例中,通过连接关系得到远程 PA 的控制代理后,实现跨设备计算加法并将结果返回到本地显示。在实际开发中,开发者可以根据需要实现多种分布式场景,例如:跨设备位置/电量等信息的采集、跨设备计算资源互助等。

  1. 设备 A 将运行时的 FA 迁移到设备 B,实现业务在设备间无缝迁移。

  1. // 跨设备迁移FA
  2. // 本地FA设置当前运行任务
  3. private ClickedListener mContinueAbilityListener = new ClickedListener() {
  4. @Override
  5. public void onClick(Component arg0) {
  6. // 用户选择设备后实现业务迁移
  7. scheduleRemoteAbility(new ISelectResult() {
  8. @Override
  9. public void onSelectResult(String deviceId) {
  10. continueAbility(deviceId);
  11. }
  12. });
  13. }
  14. };

此外,不同于启动行为,FA 的迁移还涉及到状态数据的传递。为此,继承的 IAbilityContinuation 接口为开发者提供迁移过程中特定事件的管理能力。通过自定义迁移事件相关的行为,最终实现对 Ability 的迁移。具体的定义可以参考相关的 API 文档,此处主要以较为常用的两个事件,包括迁移发起端完成迁移的回调 onCompleteContinuation(int result)以及接收到远端迁移行为传递数据的回调 onRestoreData(IntentParams restoreData)。其他还包括迁移到远端设备的 FA 关闭的回调 onRemoteTerminated()、用于本地迁移发起时保存状态数据的回调 onSaveData(IntentParams saveData)和本地发起迁移的回调 onStartContinuation()。按照实际应用自定义特定场景对应的回调,可以完成多种场景下 FA 的迁移任务。

  1. @Override
  2. public boolean onSaveData(IntentParams saveData) {
  3. String exampleData = String.valueOf(System.currentTimeMillis());
  4. saveData.setParam("continueParam", exampleData);
  5. return true;
  6. }
  7. @Override
  8. public boolean onRestoreData(IntentParams restoreData) {
  9. // 远端FA迁移传来的状态数据,开发者可以按照特定的场景对这些数据进行处理
  10. Object data = restoreData.getParam("continueParam");
  11. return true;
  12. }
  13. @Override
  14. public void onCompleteContinuation(int result) {
  15. btnContinueRemoteFA.setText("ContinueAbility Done");
  16. }

说明

  • FA 迁移可以打通设备间的壁垒,有助于不同能力的设备进行互助。前文以一个简单的例子介绍如何通过分布式任务调度提供的能力,实现 FA 跨设备的迁移(包括 FA 启动及状态数据的同步)。
  • FA 迁移过程中,远端 FA 首先接收到发起端 FA 传输的数据,再执行启动,即 onRestoreData() 发生在 onStart() 之前,详见 API 参考。
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号