0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

HarmonyOS中如何进行跨端迁移

OpenHarmony技术社区 来源:鸿蒙技术社区 作者:曾瑞绅 2021-11-15 09:38 次阅读

流转在 HarmonyOS 中泛指多设备分布式操作,也是 HarmonyOS 的亮点之一。

流转按体验可以分为跨端迁移和多端协同,这里主要跟大家讲一下如何进行跨端迁移,以及我在项目开发过程中,所遇到的问题与解决方法。

具体概念这里就不做过多的赘述了,大家可以查阅官方文档:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/hop-overview-0000001092995092

开发步骤

在开发过程中,我们可以根据业务需求分为以下两种场景:

  • 同个 FA 之间的迁移(Ability1—Ability1)

  • 不同 FA 之间的迁移(Ability1—Ability2)

下面给大家介绍一下以上两种场景的具体的开发步骤。 ①同个 FA 之间的迁移

同个 FA 之间的迁移是指不同设备端安装了同个 FA,官方文档已经有比较详细的开发步骤,下面只给大家讲一下需要注意的事项及我所遇到的问题避免大家踩坑。

我们在创建完一个 FA 之后,因为我们大部门的业务逻辑都是在 AbilitySlice,所以我们在 Ability 及 AbilitySlice 都要去实现 IAbilityContinuation 接口

并且将 Ability 中实现的 onStartContinuation()、onSaveData(IntentParams intentParams)、onRestoreData(IntentParams intentParams)的返回值,都设为 true。

publicclassMainAbilityextendsAbilityimplementsIAbilityContinuation{

@Override
publicbooleanonStartContinuation(){
returntrue;
}

@Override
publicbooleanonSaveData(IntentParamsintentParams){
returntrue;
}

@Override
publicbooleanonRestoreData(IntentParamsintentParams){
returntrue;
}
//省略部分代码
...
}

在对应的 FA 模块的 config.json 中,配置对应的权限,且在代码中也需要动态申请。
"reqPermissions":[
{
"name":"ohos.permission.DISTRIBUTED_DATASYNC"},
{
"name":"ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"},
{
"name":"ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"},
{
"name":"ohos.permission.GET_BUNDLE_INFO"}
]

if(canRequestPermission(SystemPermission.DISTRIBUTED_DATASYNC)){
//是否可以申请弹框授权(首次申请或者用户未选择禁止且不再提示)
requestPermissionsFromUser(
newString[]{SystemPermission.DISTRIBUTED_DATASYNC},PERMISSIONS_REQUEST_DISTRIBUTED);
}

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

//流转应用包名
privateStringBUNDLE_NAME="XXX.XXX.XXX";
//注册流转任务管理服务后返回的Abilitytoken
privateintabilityToken;
//用户在设备列表中选择设备后返回的设备ID
privateStringselectDeviceId;
//获取流转任务管理服务管理类
privateIContinuationRegisterManagercontinuationRegisterManager;
//设置流转任务管理服务设备状态变更的回调
privateIContinuationDeviceCallbackcontinuationDeviceCallback=newIContinuationDeviceCallback(){
@Override
publicvoidonDeviceConnectDone(StringdeviceId,StringdeviceType){
selectDeviceId=deviceId;
continuationRegisterManager.updateConnectStatus(abilityToken,selectDeviceId,DeviceConnectState.CONNECTING.getState(),null);
...
}

@Override
publicvoidonDeviceDisconnectDone(Strings){
getUITaskDispatcher().asyncDispatch(()->{
continuationRegisterManager.updateConnectStatus(abilityToken,selectDeviceId,DeviceConnectState.DIS_CONNECTING.getState(),null);
});
unRegisterContinuation();
}
};
//设置注册流转任务管理服务回调
privateRequestCallbackrequestCallback=newRequestCallback(){
@Override
publicvoidonResult(intresult){
abilityToken=result;
}
};
...

@Override
publicvoidonStart(Intentintent){
...
continuationRegisterManager=getContinuationRegisterManager();
}

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

在 Api5 的时候 IContinuationDeviceCallback 的回调接口跟官方文档有些出入,当你选择设备后会在 onDeviceConnectDone 返回你所选择的设备 ID 及设备类型。

注册流转服务之后我们便可以调起系统流转选择设备弹窗,可以通过 ExtraParams 对设备进行过滤,如不需要过滤,可不传。

ExtraParamsparams=newExtraParams();
String[]devTypes=newString[]{ExtraParams.DEVICETYPE_SMART_PHONE,ExtraParams.DEVICETYPE_SMART_WATCH,ExtraParams.DEVICETYPE_SMART_PAD};
params.setDevType(devTypes);
registerContinuation();
//显示选择设备列表
continuationRegisterManager.showDeviceList(abilityToken,params,newRequestCallback(){
@Override
publicvoidonResult(intresult){
}
});

选择完设备之后会通过上述的 IContinuationDeviceCallback 的 onDeviceConnectDone 方法进行回调。

之后通过 continueAbility 方法传入目标设备的 DeviceID,将运行的 FA 迁移到目标设备,实现业务在设备间无缝迁移。

//设置流转任务管理服务设备状态变更的回调
privateIContinuationDeviceCallbackcontinuationDeviceCallback=newIContinuationDeviceCallback(){
@Override
publicvoidonDeviceConnectDone(StringdeviceId,StringdeviceType){
selectDeviceId=deviceId;
getUITaskDispatcher().asyncDispatch(()->{
continuationRegisterManager.updateConnectStatus(abilityToken,selectDeviceId,DeviceConnectState.CONNECTING.getState(),null);
});
if(selectDeviceId!=null){
continueAbility(selectDeviceId);
}
...
}

@Override
publicvoidonDeviceDisconnectDone(Strings){
...
unRegisterContinuation();
}

};

在 FA 迁移中我觉得最主要的部分就是状态和数据的传递,要让用户体验到”无缝“的用户体验,需要通过实现 IAbilityContinuation 接口来实现数据的传递。

主要代码如下:

@Override
publicbooleanonSaveData(IntentParamssaveData){
//根据业务需求,在这里去设置需要传递的数据
saveData.setParam("continueParam",continueParam);
returntrue;
}
@Override
publicbooleanonRestoreData(IntentParamsrestoreData){
//远端FA迁移传来的状态数据,开发者可以按照自身业务对这些数据进行处理
Objectdata=restoreData.getParam("continueParam");
getUITaskDispatcher().asyncDispatch(()->{

});
returntrue;
}

需要注意的是,在 onRestoreData 处理数据更新 UI 的时候,需要在 UI 线程中去更新,否则会报错。 ②不同 FA 之间的迁移 在实际开发中可能会因为设备端的部分需求、UI 的不同,例如车机、手机、手表,从而开发了不同的 FA。

不同 FA 之间的迁移几乎与同个 FA 之间迁移配置一致,只是我们的 AbilitySlice 不需要再实现 IAbilityContinuation 接口来实现数据的同步,而是通过 Intent,具体实现如下。

首先我们先在选择设备成功后的回调 IContinuationDeviceCallback 初始化分布式环境。

//设置流转任务管理服务设备状态变更的回调
privateIContinuationDeviceCallbackcontinuationDeviceCallback=newIContinuationDeviceCallback(){
@Override
publicvoidonDeviceConnectDone(StringdeviceId,StringdeviceType){
selectDeviceId=deviceId;
//省略部分代码
...
try{
//初始化分布式环境
DeviceManager.initDistributedEnvironment(selectDeviceId,newIInitCallback(){
@Override
publicvoidonInitSuccess(Stringsuccess){

}

@Override
publicvoidonInitFailure(Stringfailure,intresult){
}
});
}catch(RemoteExceptione){
e.printStackTrace();
}
...
}
....
};

之前我们是通过 continueAbility() 方法进行跳转,而现在我们需要通过 Intent 方法进行跳转。

Intentintent=newIntent();
Operationoperation=newIntent.OperationBuilder()
.withDeviceId(deviceId)
.withBundleName(bundleName)
.withAbilityName(abilityName)
.withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
.build();
intent.setOperation(operation);
IntentParamsintentParams=newIntentParams();
//通过IntentParams传递参数
...
startAbility(intent);

在接收方,我们可以通过 onStart(Intent intent) 方法接受传递过来的参数,再根据自己的业务逻辑实现数据同步。 ③自定义设备选择弹窗 在实际项目开发中我们也可以自定义流转弹窗样式,但并不推荐这种方式,经测试发现只有在两个设备通过蓝牙连接的时候才能获取到设备列表,只有在特定的场景。

例如手机与车机、手机与手表在实际使用过程中我们基本上是会保持蓝牙连接的,通过这种方式实现流转会更稳定。但如果不能保持蓝牙实时连接的场景则不推荐。

官方 API提供了 DeviceManager.getDeviceList() 来获取远端设备,具体代码如下。

publicstaticListgetDeviceList(){
//调用DeviceManager的getDeviceList接口,通过FLAG_GET_ONLINE_DEVICE标记获得在线设备列表
ListonlineDevices=DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
//判断组网设备是否为空
if(onlineDevices==null){
LogUtil.e(TAG,"onlinedevicesisnull");
returnnewArrayList<>();
}
returnonlineDevices;
}

获取到设备列表后,我们就可以自行实现页面了,在上述的 showDeviceList() 弹出设备列表的位置替换成自己的弹窗即可。

结语

目前在 DevEco Studio 2.1 Release 以上版本已经支持跨端迁移的模拟器了。

如果没有显示出来可以在 Settings-DevEco Labs 勾选 Enable Super Device。

以上过程是在实际开发过程中慢慢摸索得出,如有不对的地方,欢迎在评论区指出,共同探讨(附下载)。
https://harmonyos.51cto.com/posts/9013

责任编辑:haq
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 鸿蒙系统
    +关注

    关注

    183

    文章

    2606

    浏览量

    65269
  • HarmonyOS
    +关注

    关注

    79

    文章

    1827

    浏览量

    29259

原文标题:HarmonyOS流转,替你踩坑了!!!

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STemWinGUI_NUM_LAYERS是如何进行宏定义的,其依据是什么?

    STemWinGUI_NUM_LAYERS 这个层数指什么,是如何进行宏定义的,其依据是什么?
    发表于 04-19 06:21

    何进行RF PA Ruggedness的测试和评估呢?

    关于PA ruggedness设计测试问题,先介绍一下原理,如何进行ruggedness的测试和评估。
    的头像 发表于 03-27 10:19 314次阅读
    如<b class='flag-5'>何进行</b>RF PA Ruggedness的测试和评估呢?

    HarmonyOS开发技术全面分析

    套系统能力、适配多种终端形态的分布式理念,能够支持多种终端设备。 ⚫ 对消费者而言, HarmonyOS 能够将生活场景的各类终端进行能力整合,形成一个“ 超级虚拟终端 ” ,可以实现不同的终端设备之间
    发表于 02-21 16:31

    鸿蒙OS 跨设备迁移

    A 上的 Page 请求迁移HarmonyOS 处理迁移任务,并回调设备 A 上 Page 的保存数据方法,用于保存迁移必须的数据。 Harm
    的头像 发表于 01-31 15:47 854次阅读

    Android APP如何进行访问硬件驱动

    本文我们要讲的是在用 i.MX8 平台开发时,Android APP 如何进行访问硬件驱动。
    的头像 发表于 12-04 13:50 470次阅读
    Android APP如<b class='flag-5'>何进行</b>访问硬件驱动

    西门子伺服电机维修如何进行调试?

    西门子伺服电机维修如何进行调试?
    的头像 发表于 11-23 11:00 582次阅读

    新apcups电源如何进行初充电

    电子发烧友网站提供《新apcups电源如何进行初充电.doc》资料免费下载
    发表于 11-15 09:55 0次下载
    新apcups电源如<b class='flag-5'>何进行</b>初充电

    DC电源模块的价格因素是什么?如何进行成本优化?

    DC电源模块的价格因素是什么?如何进行成本优化?
    的头像 发表于 11-08 10:52 321次阅读
    DC电源模块的价格因素是什么?如<b class='flag-5'>何进行</b>成本优化?

    汽车天窗淋雨设备——防水测试如何进行

    汽车天窗淋雨设备——防水测试如何进行
    的头像 发表于 10-12 08:14 740次阅读
    汽车天窗淋雨设备——防水测试如<b class='flag-5'>何进行</b>

    OpenHarmony应用模型的构成要素与Stage优势

    ,便捷实现迁移。 在多端协同场景下,应用组件具备组件间通信的RPC调用能力,天然支持设备应用组件的交互。 支持多设备和多窗口形态 应用组件管理和窗口管理在架构层面解耦: 便于系统
    发表于 09-26 16:48

    安全光幕如何进行安全保护?

    安全光幕如何进行安全保护? 许多机械设备在安装好安全光幕之后,都需要进行安全光幕的调试工作,以防止设备及安全光幕在正式运行时出现问题。那么安装安全光幕之后,光幕的调试步骤应该如何进行呢? 1:检测
    的头像 发表于 08-30 09:35 289次阅读
    安全光幕如<b class='flag-5'>何进行</b>安全保护?

    在bash中如何进行各种文件重定向呢?

    本文会用以下测试程序,来演示在bash中,如何进行各种文件重定向
    的头像 发表于 08-25 09:31 685次阅读
    在bash中如<b class='flag-5'>何进行</b>各种文件重定向呢?

    在rtthreadstudio何进行汇编的单步前进?

    在keil调试时鼠标点击反汇编窗口可以实现汇编语句的单步前进。 在rtthreadstudio中点击反汇编窗口进行单步前进依然是按c语句的单句进行执行,会一次执行很多行汇编。 在rtthreadstudio
    发表于 08-20 17:29

    HarmonyOS NEXT新能力,一站式高效开发HarmonyOS应用

    平台收集的反馈,华为整理了约16.5万条问题反馈,将问题按创新、效率、性能、可靠四个维度进行梳理。开发者提供了大量的有益建议,推动HarmonyOS在关键性能方面的不断成熟和完善。 同时
    发表于 08-14 15:08

    直线模组如何进行精度校准?

    直线模组如何进行精度校准?
    的头像 发表于 08-01 17:44 751次阅读
    直线模组如<b class='flag-5'>何进行</b>精度校准?