鸿蒙HarmonyOS开发实战—流转(跨端迁移 二)_import continuationmanager from '@ohos

39 阅读6分钟

public class MainAbilitySlice extends AbilitySlice { @Override public void onStart(Intent intent) { super.onStart(intent); // 开发者可以自行进行界面设计 // 为按钮设置统一的背景色 // 例如通过PositionLayout可以实现简单界面 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)); 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(); } }

复制

在MainAbility对应的config.json中声明跨端迁移访问的权限:ohos.permission.DISTRIBUTED_DATASYNC。在config.json中的配置如下:

{ "module": { "reqPermissions": [ { "name": "ohos.permission.DISTRIBUTED_DATASYNC", "reason": "need", "usedScene": { "ability": [ "MainAbility" ], "when": "inuse" } } ], ... } ... }

复制

此外,还需要在MainAbility的onStart()中,调用requestPermissionsFromUser()方法向用户申请权限,代码示例如下:

public class MainAbility extends Ability implements IAbilityContinuation { @Override public void onStart(Intent intent) { super.onStart(intent); // 开发者显示声明需要使用的权限 requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"}, 0); ... } ... }

复制

设置流转任务管理服务回调函数,注册流转任务管理服务,管理流转的目标设备,同时需要在流转结束时解注册流转任务管理服务。

public class MainAbilitySlice extends AbilitySlice { // 流转应用包名 private String BUNDLE_NAME = "XXX.XXX.XXX"; // 注册流转任务管理服务后返回的Ability token private int abilityToken; // 用户在设备列表中选择设备后返回的设备ID private String selectDeviceId; // 用户是否已发起可拉回流转流程 private boolean isReversibly = false; // 获取流转任务管理服务管理类 private IContinuationRegisterManager continuationRegisterManager; // 设置流转任务管理服务设备状态变更的回调 private IContinuationDeviceCallback callback = new IContinuationDeviceCallback() { @Override public void onConnected(ContinuationDeviceInfo deviceInfo) { // 在用户选择设备后设置设备ID selectDeviceId = deviceInfo.getDeviceId();

//更新选择设备后的流转状态 continuationRegisterManager.updateConnectStatus(abilityToken, selectDeviceId, DeviceConnectState.CONNECTED.getState(), null); }

@Override public void onDisconnected(String deviceId) { } }; // 设置注册流转任务管理服务回调 private RequestCallback requestCallback = new RequestCallback() { @Override public void onResult(int result) { abilityToken = result; } }; ...

@Override public void onStart(Intent intent) { ... continuationRegisterManager = getContinuationRegisterManager(); }

@Override public void onStop() { super.onStop(); // 解注册流转任务管理服务 continuationRegisterManager.unregister(abilityToken, null); // 断开流转任务管理服务连接 continuationRegisterManager.disconnect(); }

复制

为不同功能设置相应的控制按钮。

// 建议开发者按照自己的界面进行按钮设计,示例代码仅供参考 private static final int OFFSET_X = 100; private static final int OFFSET_Y = 100; private static final int ADD_OFFSET_Y = 150; private static final int BUTTON_WIDTH = 800; private static final int BUTTON_HEIGHT = 100; private static final int TEXT_SIZE = 50; private int offsetY = 0;

private Button createButton(String text, ShapeElement buttonBg) { Button button = new Button(this); button.setContentPosition(OFFSET_X, OFFSET_Y + offsetY); offsetY += ADD_OFFSET_Y; button.setWidth(BUTTON_WIDTH); button.setHeight(BUTTON_HEIGHT); button.setTextSize(TEXT_SIZE); button.setTextColor(Color.YELLOW); button.setText(text); button.setBackground(buttonBg); return button; }

// 按照顺序在PositionLayout中依次添加按钮的示例 private void addComponents(PositionLayout linear, ShapeElement buttonBg) { // 构建显示注册流转任务管理服务的按钮 Button btnRegister = createButton("register", buttonBg); btnRegister.setClickedListener(mRegisterListener); linear.addComponent(btnRegister);

// 构建显示设备列表的按钮 Button btnShowDeviceList = createButton("ShowDeviceList", buttonBg); btnShowDeviceList.setClickedListener(mShowDeviceListListener); linear.addComponent(btnShowDeviceList);

// 构建跨端迁移FA的按钮 Button btnContinueRemoteFA = createButton("ContinueRemoteFA", buttonBg); btnContinueRemoteFA.setClickedListener(mContinueAbilityListener); linear.addComponent(btnContinueRemoteFA);

// 构建可拉回迁移FA的按钮 Button btnContinueReversibly = createButton("ContinueReversibly", buttonBg); btnContinueReversibly.setClickedListener(mContinueReversiblyListener); linear.addComponent(btnContinueReversibly);

// 构建拉回FA的按钮 Button btnReverseContinue = createButton("ReverseContinuation", buttonBg); btnReverseContinue.setClickedListener(mReverseContinueListener); linear.addComponent(btnReverseContinue); }

@Override public void onStart(Intent intent) { ... //添加功能按钮布局 addComponents(layout, buttonBg); super.setUIContent(layout); }

复制

注册流转任务管理服务。

// 注册流转任务管理服务 private Component.ClickedListener mRegisterListener = new Component.ClickedListener() { @Override public void onClick(Component arg0) { HiLog.info(LABEL_LOG, "register call."); //增加过滤条件 ExtraParams params = new ExtraParams(); String[] devTypes = new String[]{ExtraParams.DEVICETYPE_SMART_PAD, ExtraParams.DEVICETYPE_SMART_PHONE}; params.setDevType(devTypes); String jsonParams = "{'filter':{'commonFilter':{'system':{'harmonyVersion':'2.0.0'},'groupType':'1|256','curComType': 0x00030004,'faFilter':'{"localVersionCode":1,"localMinCompatibleVersionCode":2,"targetBundleName": "com.xxx.yyy"}'}},'transferScene':0,'remoteAuthenticationDescription': '拉起HiVision扫描弹框描述','remoteAuthenticationPicture':''}"; params.setJsonParams(jsonParams); continuationRegisterManager.register(BUNDLE_NAME, params, callback, requestCallback); } };

复制

通过流转任务管理服务提供的showDeviceList()接口获取选择设备列表,用户选择设备后在IContinuationDeviceCallback回调中获取设备ID。

// 显示设备列表,获取设备信息 private ClickedListener mShowDeviceListListener = new ClickedListener() { @Override public void onClick(Component arg0) { // 设置过滤设备类型 ExtraParams params = new ExtraParams(); String[] devTypes = new String[]{ExtraParams.DEVICETYPE_SMART_PAD, ExtraParams.DEVICETYPE_SMART_PHONE}; params.setDevType(devTypes); String jsonParams = "{'filter':{'commonFilter':{'system':{'harmonyVersion':'2.0.0'},'groupType':'1|256','curComType': 0x00030004,'faFilter':'{"localVersionCode":1,"localMinCompatibleVersionCode":2,"targetBundleName": "com.xxx.yyy"}'}},'transferScene':0,'remoteAuthenticationDescription': '拉起HiVision扫描弹框描述','remoteAuthenticationPicture':''}"; params.setJsonParams(jsonParams);

// 显示选择设备列表 continuationRegisterManager.showDeviceList(abilityToken, params, null); } };

复制

可使用两种方法实现FA的迁移。

  • 方法一:直接迁移FA,迁移后不可回迁。
  • 方法二:迁移一个支持回迁的FA,迁移后还可将FA拉回到本端。

将运行时的FA迁移到目标设备,实现业务在设备间无缝迁移。

// 跨端迁移FA private ClickedListener mContinueAbilityListener = new ClickedListener() { @Override public void onClick(Component arg0) { if (selectDeviceId != null) { // 用户点击后发起迁移流程 continueAbility(selectDeviceId); } } };

复制

设置一个支持回迁FA的迁移功能按钮,以及拉回该FA的功能按钮。

// 设置支持回迁FA的迁移按钮 private Component.ClickedListener mContinueReversiblyListener = new Component.ClickedListener() { @Override public void onClick(Component arg0) { if (selectDeviceId != null) { // 用户选择设备后实现可拉回迁移 continueAbilityReversibly(selectDeviceId); isReversibly = true; } } };

// 设置拉回已迁移FA的按钮 private Component.ClickedListener mReverseContinueListener = new Component.ClickedListener() { @Override public void onClick(Component arg0) { // 用户拉回迁移FA if (isReversibly) { reverseContinueAbility(); isReversibly = false; } } };

复制

FA的迁移还涉及到状态数据的传递,需要实现IAbilityContinuation接口,供开发者实现迁移过程中特定事件的管理能力,代码示例如下:

public class MainAbilitySlice extends AbilitySlice implements IAbilityContinuation { private void showMessage(String msg) { ToastDialog toastDialog = new ToastDialog(this); toastDialog.setText(msg); toastDialog.show(); }

@Override public boolean onStartContinuation() { showMessage("ContinueAbility Start"); return true; }

@Override public boolean onSaveData(IntentParams saveData) { String exampleData = String.valueOf(System.currentTimeMillis()); saveData.setParam("continueParam", exampleData); return true; }

@Override public boolean onRestoreData(IntentParams restoreData) { // 远端FA迁移传来的状态数据,开发者可以按照特定的场景对这些数据进行处理 Object data = restoreData.getParam("continueParam"); return true; }

@Override public void onCompleteContinuation(int result) { // 开发者可以根据业务需要,提示用户迁移完成,关闭本端FA showMessage("ContinueAbility Done"); if (!isReversibly) { terminateAbility(); } }

@Override public void onFailedContinuation(int errorCode) { // 开发者可以根据业务需要,提示用户迁移失败 showMessage("ContinueAbility failed"); if (!isReversibly) { terminateAbility(); } } }

复制

通过自定义迁移事件相关的行为,最终实现对FA的迁移。此处主要以较为常用的两个事件,包括迁移发起端完成迁移的回调onCompleteContinuation(int result),以及接收到远端迁移行为传递数据的回调onRestoreData(IntentParams restoreData)。其他还包括用于本端迁移发起时保存状态数据的回调onSaveData(IntentParams saveData)和本端发起迁移的回调onStartContinuation()。按照实际应用自定义特定场景对应的回调,可以完成多种场景下FA的迁移任务。


最后,为了能让大家更好的去学习提升鸿蒙 (Harmony OS) 开发技术,小编连夜整理了一份30个G纯血版学习资料(含视频电子书学习文档等)以及一份在Github上持续爆火霸榜的《纯血版华为鸿蒙 (Harmony OS)开发手册》(共计890页),希望对大家有所帮助。

纯血版鸿蒙 HarmonyOS 4.0 视频学习资料

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

img img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取