当前位置: 首页 > 科技观察

PageAbility跨设备迁移开发实践—问答互动

时间:2023-03-20 01:28:34 科技观察

更多内容请访问:Harmonyos.51cto.com,与华为官方共同打造的鸿蒙技术社区页面迁移至另一设备。应用数据可以在不同设备间同步甚至迁移是HarmonyOS的一大特色。于是,我以官方的分布式邮件系统为例,写了一个简单的问答交互应用。用户在设备A上提问,在设备B上回答,通过迁移传递信息,可以查看问答记录。目录效果显示,主要功能实现了问答界面,问答等信息通过发送按钮传递到另一台设备。实现问题记录接口,记录每一个完整的问题和答案,方便查看。设备间数据同步,问答记录相同。迁移的主要步骤设备A上的页面请求迁移。HarmonyOS处理迁移任务,回调设备A上Page的数据保存方法,保存迁移需要的数据。HarmonyOS在设备B上启动同一个Page,并回调其数据恢复方法。PageAbility实现迁移是需要实现IAbilityContinuation接口的,该接口如下:////Sourcecoderecreatedfroma.classfilebyIntelliJIDEA//(poweredbyFernFlowerdecompiler)//packageohos.aafwk.ability;importohos.aafwk.content.IntentParams;publicinterfaceIAbilityContinuation{intERR_ABILITY_QUERY_FAILED=-2;intERR_CONTINUE_TIMEOUT=-8;intERR_DEVICE_OFFLINE=-9;intERR_INSTALL_FREE_NOT_SUPPORTED=-4;intERR_NETWORK_UNAVAILABLE=-3;intERR_PARAMETER_INVALID=-6;intERR_PERMISSION_DENIED=-5;intERR_REMOTE_DEVICE_INCOMPATIBLE=-7;intERR_UNKNOWN=-1;intSUCCESS=0;booleanonStartContinuation();booleanonSaveData(IntentParamsvar1);booleanonRestoreData(IntentParamsvar1);voidonCompleteContinuation(intvar1);defaultvoidonRemoteTerminated(){thrownewRuntimeException("Stub!");}defaultvoidonFailedContinuation(terrorCode){thrownewRuntimeException("Stub!");}}除了一些异常代码枚举外,都是迁移中需要用到的主接口,onStartContinuation()是迁移开始前的预处理函数,可以在这里添加一些条件检测,提示等。但在开始请求迁移之前,您需要申请权限ohos.permission.DISTRIBUTED_DATASYNC。config.json中的配置如下:config.json"reqPermissions":[{"name":"ohos.permission.DISTRIBUTED_DATASYNC"}]接下来只需要PageAbility在Ability中实现onRequestPermissionsFromUserResult接口即可完成权限启用迁移应用。@OverridepublicvoidonRequestPermissionsFromUserResult(intrequestCode,String[]permissions,int[]grantResults){if(permissions==null||permissions.length==0||grantResults==null||grantResults.length==0){return;}if(requestCode==0){if(grantResults[0]==IBundleManager.PERMISSION_DENIED){terminateAbility();}}}完成权限申请后,只需要通过事件触发迁移开关即可。迁移开关continueAbility()可以通过按钮的点击事件来触发,如下:Resource_Table.).setClickedListener(this::migrateAbility);findComponentById(ResourceTable.Id_return_button).setClickedListener(component->terminate());}privatevoidmigrateAbility(Componentcomponent){StringquestionSend=questionTextField.getText();StringanswerSend=answerTextField.getText()复制代码;if(questionSend.isEmpty()&&answerSend.isEmpty()){newToastDialog(this).setText("Textcannotbenull").show();return;}try{continueAbility();}catch(IllegalStateExceptionillegalStateException){HiLog.error(LABEL_LOG,"%{public}s","migrateAbility:IllegalStateException");}}最重要的两个接口是onSaveData和onRestoreData。一种是存储设备A在迁移时需要输入的数据,另一种是设备B在迁移时,恢复数据。@OverridepublicbooleanonSaveData(IntentParamsintentParams){intentParams.setParam(QUESTION_KEY,questionTextField.getText());intentParams.setParam(ANSWER_KEY,answerTextField.getText());returntrue;}@OverridepublicbooleanonRestoreData(IntentParamsintentParams){if(intentParams.getParam)(QUESTIONKEY)){questionText=(String)intentParams.getParam(QUESTION_KEY);}if(intentParams.getParam(ANSWER_KEY)instanceofString){answerText=(String)intentParams.getParam(ANSWER_KEY);}if(!questionText.isEmpty()&&!answerText.isEmpty()){AskRecordSlice.UpdateContent("Q:"+questionText+"\n");AskRecordSlice.UpdateContent("A:"+answerText+"\n");}returntrue;}IntentParams为要迁移的数据包,提供setParam,getParam,传输Key-Value数据。只要B设备上的onRestoreData运行正常,A设备上的onCompleteContinuation就会被回调,表示迁移成功。否则会回调onFailedContinuation,通过捕获异常码来处理异常。正常迁移完成后,我对问答记录进行了本地存储:@OverridepublicvoidonCompleteContinuation(intcode){questionText=questionTextField.getText();answerText=answerTextField.getText();if(!questionText.isEmpty()&&!answerText.isEmpty()){AskRecordSlice.UpdateContent("Q:"+questionText+"\n");AskRecordSlice.UpdateContent("A:"+answerText+"\n");}}具体代码由于大目录树中的文件数。工程文件的git路径为:https://gitee.com/baboon-chen/harmony-osexample.git特别注意点://1跨设备时,需要在配置文件.json"deviceType":["phone","tablet"],//2实现接口的类有哪些?一个应用程序可能包含多个页面,每个页面都有自己的PageSlice堆栈。您只需要在支持迁移的Page中通过以下方法实现IAbilityContinuation接口即可。同时,该Page包含的所有AbilitySlices也需要实现该接口。更多信息请访问:Harmonyos.51cto.com,与华为官方合作打造的鸿蒙技术社区