【木棉花】学习笔记--分布式迁移 原创 精华

木棉花沈泳鑫
发布于 2021-9-2 17:29
浏览
5收藏

前言

鸿蒙开发相对于安卓开发最大的优势就是鸿蒙开发拥有分布式能力,那我的前两篇学习笔记中的分布式数据库就涉及到分布式能力,还不了解什么是分布式能力的同学就可以去官网上了解一下,这里就不多加赘述了,或者也可以查看我上一篇学习笔记了解一下。
那今天我要整理到学习笔记中的呢,就是在分布式能力里算是比较简单的分布式迁移
为了更好地熟练掌握鸿蒙手机应用开发,为了供大家更方便的学习鸿蒙手机的应用开发,我会将所有的笔记都整理到Awesome-HarmonyOS_木棉花,更多详细学习资料请查看Awesome-HarmonyOS_木棉花
现在就开始我们今天的学习之旅吧!!!
【木棉花】学习笔记--分布式迁移-鸿蒙开发者社区


正文

应用目的&&效果

那首先什么是分布式迁移?该应用中实现了什么?那迁移就是例如手机的邮寄编辑到一般将邮寄迁移到iPad继续编辑。分布式迁移提供了一个主动迁移接口及一系列页面生命周期回调,以支持将本地业务无缝迁移到指定设备中。在该应用中,我会编写一个文本输入框,还有一个按钮用于迁移的动作,在一台设备中在文本输入框中输入数据,点击迁移按钮,就可以将该页面迁移到另外一台设备上去继续运行了。
【木棉花】学习笔记--分布式迁移-鸿蒙开发者社区
【木棉花】学习笔记--分布式迁移-鸿蒙开发者社区
当然也可以在被迁移的设备上继续输入数据,迁移回原设备。
【木棉花】学习笔记--分布式迁移-鸿蒙开发者社区
【木棉花】学习笔记--分布式迁移-鸿蒙开发者社区

创建工程

同样的,我们还是创建一个java的工程,然后将工程命名为 MyMigrate。
【木棉花】学习笔记--分布式迁移-鸿蒙开发者社区
具体是怎么实现的就可以参考我的前两篇学习笔记:分布式数据库轻量级偏好数据库学习笔记,里面有详细的介绍。
接下来又是熟悉的设计UI界面的步骤。

设计UI界面

我们在background_ability_main文件中增加圆角半径的修饰。background_ability_main文件代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
       ohos:shape="rectangle">
    <solid
        ohos:color="#FFFFFF"/>
    <corners
        ohos:radius="20"/>
</shape>

同时,我们还需要在graphic中增加一个名为background_button的文件来作为按钮的背景。代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
       ohos:shape="rectangle">
    <solid
        ohos:color="#007DFF"/>
    <corners
        ohos:radius="100"/>
</shape>

那前期准备工作就OK了,我们接下来的动作就是在ability_main中完成UI界面的设计。
首先,我们是需要把这个页面的背景设置为浅灰色的,那我们就需要就DirectionalLayout容器中增加设置背景的代码,增加一个文本输入框TextField,在其中引用background_ability_main作为背景,还有设置大小,提示输入等等,还有增加一个按钮。ability_main代码如下:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:orientation="vertical"
    ohos:background_element="#FFE7E7E7">

    <TextField
        ohos:id="$+id:textfield"
        ohos:height="150vp"
        ohos:width="match_parent"
        ohos:background_element="$graphic:background_ability_main"
        ohos:layout_alignment="horizontal_center"
        ohos:margin="40vp"
        ohos:hint="请输入..."
        ohos:text_size="30vp"
        />

    <Button
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:id="$+id:migrate"
        ohos:background_element="$graphic:background_button"
        ohos:top_padding="8vp"
        ohos:bottom_padding="8vp"
        ohos:left_padding="19vp"
        ohos:right_padding="19vp"
        ohos:top_margin="20vp"
        ohos:text="迁移"
        ohos:text_color="#FFFFFF"
        ohos:text_size="25vp"/>

</DirectionalLayout>

增加权限

一旦设计某些敏感动作的时候我们是需要给手机授予相关的权限的。例如在该应用中涉及的权限就是数据交换,这是一个经常用到的权限。
在config.json的abilities之前添加非敏感权限,非敏感权限是可以直接加的,可以不需要通过弹窗的形式来得到用户的许可的。

"reqPermissions": [
      {
        "name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
      },
      {
        "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
      },
      {
        "name": "ohos.permission.GET_BUNDLE_INFO"
      },
      {
        "name": "ohos.permission.DISTRIBUTED_DATASYNC"
      }
    ],

同时有非敏感权限就会有敏感权限,敏感权限就不仅是需要在config.json里添加了,我们还需要以弹窗的形式来让用户确定授予该权限,在MainAbility的onStart中添加如下代码:

requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"},0);

迁移动作的编写

首先,我们要在MainAbility文件中给MainAbility增加一个 IAbilityContinuation 接口,该接口定义了迁移的相关方法。
即在 public class MainAbilitySlice extends AbilitySlice 后添加 implements IAbilityContinuation,那这时候就增加的代码就会标红,这是因为少了生成该类的默认实现方法。那可以将鼠标移动至红线处,点击"Implement methods",就会自动帮我们添加生成该类的相关方法的默认实现。
【木棉花】学习笔记--分布式迁移-鸿蒙开发者社区
然后就是将增加的这几个方法中的返回值改为真。
【木棉花】学习笔记--分布式迁移-鸿蒙开发者社区
那同样的我们还需要在MainAbilitySlice中给MainAbilitySlice增加相同的接口。
接下来是在MainAbilitySlice定义三个私有变量。

    private static TextField textField;
    private static Button button_migrate;
    private static String string = ""; //用于读取文本框中的数据

1.当我们点击迁移按钮时,首先是会运行函数“onStartContinuation”,在该函数中可以通过弹窗的形式来让用户决定迁不迁移,当然最简单的方法就是直接将返回值改为真,确定迁移的动作。
2.接下来就是运行“onSaveData”函数,在该函数是将该页面的数据保存下来,可以用于迁移完成后页面数据的恢复。在该方法中,我们将文本框中的数据以键值对的形式写入“intentParam”,通过intentParams传到另外一部手机。并将返回值修改为真。
3.下面就是会在目标设备上运行“onRestoreData”,当然看这个函数名就可以大概猜到这是用于目标设备数据恢复的函数的。那在该函数中我们就需要将“intentParams”中携带的数据保存下来,然后在将返回值修改为真。
4.上面数据恢复完之后就会去开始目标设备的生命周期。
5.最后,在完成迁移的动作之后就会运行原设备的“onCompleteContinuation”,在该函数中可以完成迁移完成后的动作,例如将原设备的页面销毁。
其代码如下:

@Override
    public boolean onStartContinuation() { //IAbilityContinuation 这个类的相关方法的默认实现
        return true; //1.可以在该方法中决定迁不迁移,可以实现一个弹出窗口来确认迁移。不过最简单的方法就是直接 return true 确定迁移
    }

    @Override
    public boolean onSaveData(IntentParams intentParams) {
        intentParams.setParam("data",textField.getText());
        return true;//2.会在该方法中保存当前页面的状态数据,将保存好的数据通过 intentParams 发送到迁移的另外一部设备
    }

    @Override
    public boolean onRestoreData(IntentParams intentParams) {
        string = intentParams.getParam("data").toString();
        return true; //3.目标设备通过 intentParams 传送来的数据恢复页面 恢复完数据之后就会开始目标设备的生命周期
    }

    @Override
    public void onCompleteContinuation(int i) {
        terminateAbility(); //迁移完成后就会执行迁移设备的该函数,可以在该函数中执行迁移完成后想做的动作,例如销毁迁移设备的页面
    }

那接下来我们就需要编写点击按钮对应的迁移事件了。

        textField = (TextField)findComponentById(ResourceTable.Id_textfield);
        textField.setText(string); //将文本框中的数据设置为string中的内容

        button_migrate = (Button)findComponentById(ResourceTable.Id_migrate);
        button_migrate.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                continueAbility(); //迁移对应的函数
            }
        });

至此该迁移的应用就已经算是全部完成了。这样就可以完成我们文章一开始想要实现的效果了。那完成这一遍的学习之后,可以试着编写一个可以迁移的游戏来玩一玩了。
整个迁移的动作我们可以用一张时序图来表示。
【木棉花】学习笔记--分布式迁移-鸿蒙开发者社区
这样看起来就会更加清晰明了。

结语

源码就放在附件中了,压缩包解压之后可以直接在编译器中运行,可以供大家下载之后跑一下试试看效果,大家有什么看不懂的地方可以私信问我或者对照源码进行学习。最后最后再不要脸的重申一遍更多学习资料学习笔记,请关注Awesome-HarmonyOS_木棉花。如果有遇到什么问题,或者查找出其中的错误之处,或者能够优化代码和界面,也欢迎各位在评论区留言讨论,让我们一起学习进步!
【木棉花】学习笔记--分布式迁移-鸿蒙开发者社区

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
MyMigrate.rar 1.08M 27次下载
已于2021-9-2 17:29:54修改
10
收藏 5
回复
举报
10条回复
按时间正序
/
按时间倒序
Der_带鱼
Der_带鱼

支持!

回复
2021-9-5 18:08:37
木棉花沈泳鑫
木棉花沈泳鑫 回复了 Der_带鱼
支持!

谢谢你的支持

回复
2021-9-5 23:52:23
爱吃土豆丝的打工人
爱吃土豆丝的打工人

真机上面可以实现迁移不  我跨设备迁移  在真机上没有反应

回复
2021-9-6 09:18:18
无妻徒刑一百年
无妻徒刑一百年 回复了 爱吃土豆丝的打工人
真机上面可以实现迁移不 我跨设备迁移 在真机上没有反应

几个月前我这边测试这个功能时,需要设备都登录同个华为账号,不知道现在改了没得。

回复
2021-9-6 10:28:33
木棉花沈泳鑫
木棉花沈泳鑫 回复了 爱吃土豆丝的打工人
真机上面可以实现迁移不 我跨设备迁移 在真机上没有反应

那个我还没试过,我只是在模拟器上试过

回复
2021-9-6 20:26:43
爱吃土豆丝的打工人
爱吃土豆丝的打工人 回复了 木棉花沈泳鑫
那个我还没试过,我只是在模拟器上试过

你试试真机上行不行   我真机上没反应

 

回复
2021-9-8 17:09:17
木棉花沈泳鑫
木棉花沈泳鑫 回复了 爱吃土豆丝的打工人
你试试真机上行不行 我真机上没反应

好像真机上是没啥反应的

回复
2021-9-9 18:47:42
爱吃土豆丝的打工人
爱吃土豆丝的打工人 回复了 木棉花沈泳鑫
好像真机上是没啥反应的

找官方  也没人给解决一下  追问了一周多了  /捂脸哭

回复
2021-9-10 09:30:35
吃饱了没事做
吃饱了没事做

请问JS上写的迁移 没反应。代码也是照着官方的文档写的。权限也申请了。远程模拟机没法迁移

代码写的没问题,调用FeatureAbility.continueAbility();返回的对象的code的值也是0,说明成功发起迁移了。但onStartContinuation等几个跟迁移有关的生命周期回调没有被调用,请问代码哪里出了问题,是照着官方给的案例写的。也对照的官方给的代码,没发现哪里写错了。工具里也调用了super device,也通过super app 启动程序了。

e6f4d01762e0b37785a3239a5323f21255341a.png

js代码如下:

import app from '@system.app';
export default {
    data: {
       appData:{
           message:["demo1","demo2"],
           msg:""
       }
    },

    getMsg(e){
        this.appData.msg = e.value;
    },
    send(){
        console.info("---"+this.appData.message)
        this.appData.message.push(this.appData.msg);
        this.appData.msg = "";
        console.info("---"+this.appData.message)
    },
    async start(){
        let result = await FeatureAbility.continueAbility();
        console.info("---result:" + JSON.stringify(result));
    },
    onStartContinuation(){
        console.info("---onStartContinuation")
        return true;
    },
    onSaveData(saveData){
        Object.assign(saveData,this.appData);
        //console.info("---onSaveData")
    },
    onRestoreData(restoreData){
        this.appData = restoreData;
        //console.info("---onRestoreData")
    },
    onCompleteContinuation(){
        app.terminate();
        //console.info("---onCompleteContinuation")
    }
}

复制

HML文件的代码如下:

<div class="container">
    <div>
        <list>
            <list-item for="{{appData.message}}" class="msg-css">
                <text >{{$item}}</text>
            </list-item>
        </list>
    </div>
    <div class="bottom-css">
        <input type="text" @change="getMsg"></input>
        <button type="capsule" @click="send">发送</button>
        <button type="capsule" @click="switch">跳转</button>
        <button type="capsule" @click="start">迁移</button>
    </div>
</div>

复制

权限也配置了

"ohos.permission.DISTRIBUTED_DATASYNC"权限也配置在config.json里了,

Java里也写了有关的代码

public class MainAbility extends AceAbility {
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"},0);
    }

    @Override
    public void onStop() {
        super.onStop();
    }
回复
2023-3-21 10:59:13
wx641fab9a3a736
wx641fab9a3a736 回复了 木棉花沈泳鑫
那个我还没试过,我只是在模拟器上试过

模拟器上,仍需要设备登陆同个华为账号吗


回复
2023-3-29 10:23:01
回复
    相关推荐