Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Docs
提交
b1b29ea2
D
Docs
项目概览
OpenHarmony
/
Docs
大约 1 年 前同步成功
通知
159
Star
292
Fork
28
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
Docs
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
b1b29ea2
编写于
3月 23, 2022
作者:
O
openharmony_ci
提交者:
Gitee
3月 23, 2022
浏览文件
操作
浏览文件
下载
差异文件
!2374 跨端迁移开发指导更新
Merge pull request !2374 from wangdongdong/0318
上级
d41b292e
1d5625a8
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
152 addition
and
98 deletion
+152
-98
zh-cn/application-dev/ability/Readme-CN.md
zh-cn/application-dev/ability/Readme-CN.md
+1
-1
zh-cn/application-dev/ability/figures/continuation-info.png
zh-cn/application-dev/ability/figures/continuation-info.png
+0
-0
zh-cn/application-dev/ability/stage-ability-continuation.md
zh-cn/application-dev/ability/stage-ability-continuation.md
+151
-97
未找到文件。
zh-cn/application-dev/ability/Readme-CN.md
浏览文件 @
b1b29ea2
...
...
@@ -8,7 +8,7 @@
-
[
FormAbility开发指导
](
fa-formability.md
)
-
Stage模型
-
[
ServiceExtensionAbility开发指导
](
stage-serviceextension.md
)
-
[
应用
迁移开发指导
](
stage-ability-continuation.md
)
-
[
跨端
迁移开发指导
](
stage-ability-continuation.md
)
-
[
Call调用开发指导
](
stage-call.md
)
-
其他
-
[
WantAgent使用指导
](
wantagent.md
)
...
...
zh-cn/application-dev/ability/figures/continuation-info.png
0 → 100755
浏览文件 @
b1b29ea2
13.4 KB
zh-cn/application-dev/ability/stage-ability-continuation.md
100644 → 100755
浏览文件 @
b1b29ea2
#
应用
迁移开发指导
#
跨端
迁移开发指导
## 场景介绍
迁移的主要工作是实现将应用当前任务,包括页面部分数据、栈信息等,迁移到远端设备。迁移成功后,本端任务将被清除;若失败则不会,可允许再次迁移。
迁移的主要工作是实现将应用当前任务,包括页面控件状态变量、分布式对象等,迁移到远端设备。页面控件状态变量用于同步页面UI数据,分布式对象用于同步内存中的数据。
## 接口说明
迁移提供的能力如下,具体的API详见
接口文档
迁移提供的能力如下,具体的API详见
[
接口文档
](
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-application-ability.md
)
。
**表1**
应用迁移API接口功能介绍
|接口名 | 描述|
|:------ | :------|
| onContinue(wantParams : {[key: string]: any}) | 迁移发起端在该回调中保存迁移所需要的数据,同时返回是否同意迁移:true表示同意,false表示拒绝。 |
| onContinue(wantParams : {[key: string]: any}): OnContinueResult | 迁移
**发起端**
在该回调中保存迁移所需要的数据,同时返回是否同意迁移:0表示同意,拒绝返回相应错误码。 |
| onCreate(want: Want,param:LaunchParam): void | 迁移
**目标端**
在该回调中完成数据恢复,并触发页面恢复。 |
|
**enum**
OnContinueResult | onContinue的返回值类型:AGREE表示同意;REJECT表示拒绝;MISMATCH表示版本不匹配 |
## 开发步骤
**图1**
迁移开发示意图
### 迁移应用
![
continuation_dev
](
figures/continuation-info.png
)
## 开发步骤
### 迁移应用
1.
配置
-
配置应用支持迁移
在config.json中配置continuable字段:true表示支持迁移,false表示不支持,默认为false.
在module.json5中配置continuable字段:true表示支持迁移,false表示不支持,默认为false。配置为false的应用将被系统识别为无法迁移。
```
```
javascript
"
continuable
"
:
true
```
配置为false的应用将无法在任务中心进行迁移。
*
配置应用启动类型
迁移当前只支持多实例应用,需要在在config.json
中配置launchType字段为standard
迁移当前只支持多实例应用,需要在在module.json5
中配置launchType字段为standard
```
```
javascript
"
launchType
"
:
"
standard
"
```
*
申请分布式权限
支持跨端迁移的应用需要在module.json5申请分布式权限 DISTRIBUTED_DATASYNC。
```
javascript
"
requestPermissions
"
:
[
{
"
name
"
:
"
ohos.permission.DISTRIBUTED_DATASYNC
"
},
```
这个权限需要在应用首次启动的时候弹窗让用户授予,可以通过在ability的onWindowStageCreate中添加如下代码实现
```
javascript
requestPermissions
=
async
()
=>
{
let
permissions
:
Array
<
string
>
=
[
"
ohos.permission.DISTRIBUTED_DATASYNC
"
];
let
needGrantPermission
=
false
let
accessManger
=
accessControl
.
createAtManager
()
Logger
.
info
(
"
app permission get bundle info
"
)
let
bundleInfo
=
await
bundle
.
getApplicationInfo
(
BUNDLE_NAME
,
0
,
100
)
Logger
.
info
(
`app permission query permission
${
bundleInfo
.
accessTokenId
.
toString
()}
`
)
for
(
const
permission
of
permissions
)
{
Logger
.
info
(
`app permission query grant status
${
permission
}
`
)
try
{
let
grantStatus
=
await
accessManger
.
verifyAccessToken
(
bundleInfo
.
accessTokenId
,
permission
)
if
(
grantStatus
===
PERMISSION_REJECT
)
{
needGrantPermission
=
true
break
;
}
}
catch
(
err
)
{
Logger
.
error
(
`app permission query grant status error
${
permission
}
${
JSON
.
stringify
(
err
)}
`
)
needGrantPermission
=
true
break
;
}
}
if
(
needGrantPermission
)
{
Logger
.
info
(
"
app permission needGrantPermission
"
)
try
{
await
this
.
context
.
requestPermissionsFromUser
(
permissions
)
}
catch
(
err
)
{
Logger
.
error
(
`app permission
${
JSON
.
stringify
(
err
)}
`
)
}
}
else
{
Logger
.
info
(
"
app permission already granted
"
)
}
}
```
2.
实现onContinue接口
onContinue接口在
**发起端**
被调用,主要用于在迁移发起时,通知开发者保存控件状态变量和内存中数据,准备迁移。当应用准备完成后,需要返回OnContinueResult.AGREE(0)表示同意迁移,否则返回相应的错误码拒绝迁移。如果不实现该接口,系统将默认为拒绝迁移。
导入模块
```
```
javascript
import
Ability
from
'
@ohos.application.Ability
'
;
import
AbilityConstant
from
'
@ohos.application.AbilityConstant
'
;
```
-
要实现迁移,此接口必须实现并返回
true
,否则默认为拒绝迁移。
-
要实现迁移,此接口必须实现并返回
AGREE
,否则默认为拒绝迁移。
-
示例
```
javascript
onContinue
(
wantParams
:
{[
key
:
string
]:
any
})
{
console
.
log
(
"
MainAbility onContinue
"
)
return
true
;
onContinue
(
wantParam
:
{[
key
:
string
]:
any
})
{
Logger
.
info
(
"
onContinue using distributedObject
"
)
// set user input data into want params
wantParam
[
"
input
"
]
=
AppStorage
.
Get
<
string
>
(
'
ContinueInput
'
);
Logger
.
info
(
`onContinue input =
${
wantParam
[
"
input
"
]}
`
);
return
AbilityConstant
.
OnContinueResult
.
AGREE
}
```
...
...
@@ -70,7 +130,9 @@
3.
在onCreate接口中实现迁移逻辑
-
远端设备上,在onCreate中根据launchReason判断该次启动是否为迁移LaunchReason.CONTINUATION(3)
onCreate接口在迁移
**目标端**
被调用,在目标端ability被拉起时,通知开发者同步已保存的内存数据和控件状态,完成后触发页面的恢复。如果不实现该接口中迁移相关逻辑,ability将会作为普通的启动方式拉起,无法恢复页面。
-
远端设备上,在onCreate中根据launchReason判断该次启动是否为迁移LaunchReason.CONTINUATION
-
完成数据恢复后,开发者需要调用
**restoreWindowStage**
来触发页面恢复。
...
...
@@ -79,60 +141,56 @@
*
示例
```
javascript
onCreate
(
want
,
launchParam
)
{
// Ability is creating, initialize resources for this ability
console
.
log
(
"
MainAbility onCreate
"
,
launchParam
.
launchReason
);
if
(
launchParam
.
launchReason
==
LaunchReason
.
CONTINUATION
)
{
this
.
contentStorage
=
new
ContenStorage
();
onCreate
(
want
,
launchParam
)
{
Logger
.
info
(
`MainAbility onCreate
${
AbilityConstant
.
LaunchReason
.
CONTINUATION
}
`
)
globalThis
.
abilityWant
=
want
;
if
(
launchParam
.
launchReason
==
AbilityConstant
.
LaunchReason
.
CONTINUATION
)
{
let
input
=
want
.
parameters
.
input
// get user data from want params
AppStorage
.
SetOrCreate
<
string
>
(
'
ContinueInput
'
,
input
)
Logger
.
info
(
`onCreate for continuation sessionId:
${
this
.
sessionId
}
`
)
this
.
contentStorage
=
new
ContentStorage
();
this
.
context
.
restoreWindowStage
(
this
.
contentStorage
);
}
}
```
### 迁移数据
1.
使用
自定义数据
1.
使用
分布式对象
-
wantParams中可以填写key-value形式自定义数据,key类型string,填充的数据将随want被传输到远端,用于携带一些简单、轻量的数据
。
分布式数据对象提供了与本地变量类似的操作,实现两个设备的数据同步,当设备1的应用A的分布式数据对象增、删、改数据后,设备2的应用A也可以获取到对应的数据变化,同时还能监听数据变更以及对端数据对象的上下线。用法详见
[
分布式对象指导文档
](
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/database/database-distributedobject-guidelines.md
)
。
迁移场景中,分布式对象(distributedDataObject)主要用于将本机内存数据同步到目标设备。
```
javascript
onContinue
(
wantParams
:
{[
key
:
string
]:
any
})
{
console
.
log
(
"
Continue My Data
"
)
wantParams
[
"
myData
"
]
=
"
my1234567
"
;
return
true
;
}
```
-
同时在远端判断如果是迁移,可以从want.parameters中取出在发起端保存的自定义数据。
-
发起端在onContinue中,将待迁移的数据存入分布式对象中,然后设置好session id,并通过wantParams将session id传到远端设备。
```javascript
onCreate
(
want
,
launchParam
)
{
if
(
launchParam
.
launchReason
==
LaunchReason
.
CONTINUATION
)
{
console
.
log
(
"
onCreate LaunchReason = CONTINUATION
"
,
want
.
parameters
[
"
myData
"
]);
// my1234567
...
this
.
context
.
restoreWindowStage
(
this
.
contentStorage
);
}
}
```
2.
使用分布式对象
使用分布式对象可以传输更多的数据到远端设备,更多用法详见分布式对象接口文档。
import Ability from '@ohos.application.Ability';
import distributedObject from '@ohos.data.distributedDataObject';
-
发起端在onContinue中,将待迁移的数据存入分布式对象中,然后设置好session id,并通过wantParams将session id传到远端设备。
var g_object = distributedObject.createDistributedObject({name:undefined});
export default class MainAbility extends Ability {
contentStorage : ContenStorage
sessionId : string;
-
远端设备在onCreate中,取出发起端传过来的session id,建立分布式对象并关联该session id,这样就能实现分布式对象的同步。需要注意的是,在调用restoreWindowStage之前,迁移需要的分布式对象必须全部关联完,保证能够获取到正确的数据。
onContinue(wantParam : {[key: string]: any}) {
Logger.info("onContinue using distributedObject")
this.sessionId = distributedObject.genSessionId();
//set distributed data object session id
g_object.setSessionId(this.sessionId);
g_object.name = "Amy";
// set session id into want params
wantParam["session"] = this.sessionId;
return AbilityConstant.OnContinueResult.AGREE
}
```
*
示例
- 目标设备在onCreate中,取出发起端传过来的session id,建立分布式对象并关联该session id,这样就能实现分布式对象的同步。需要注意的是,在调用restoreWindowStage之前,迁移需要的分布式对象必须全部关联完,保证能够获取到正确的数据。
```
javascript
import Ability from '@ohos.application.Ability';
...
...
@@ -141,38 +199,34 @@
var g_object = distributedObject.createDistributedObject({name:undefined});
export default class MainAbility extends Ability {
contentStorage
:
Conten
Storage
contentStorage : Content
Storage
sessionId : string;
onCreate
(
want
,
launchParam
)
{
if
(
launchParam
.
launchReason
==
3
)
{
this
.
sessionId
=
want
.
parameters
[
"
session
"
]
// 取出session id
function
statusCallback
(
sessionId
,
networkid
,
status
)
{
console
.
info
(
"
object status change sessionId:
"
+
sessionId
+
"
status:
"
+
status
+
"
g_object.name:
"
+
g_object
.
name
);
// 回调中可以取到同步过来的分布式对象内容 name = Amy
statusCallback(sessionId, networkid, status) {
Logger.info(
`continuation object status change, sessionId: ${sessionId}, status: ${status}, g_object.name: ${g_object.name}`
)
}
g_object
.
on
(
"
status
"
,
statusCallback
);
// 注册分布式对象同步结果的监听
g_object
.
setSessionId
(
this
.
sessionId
);
// 将本地分布式对象也关联发起端的session id
onCreate(want, launchParam) {
Logger.info(
`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`
)
if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
// get distributed data object session id from want params
this.sessionId = want.parameters.session
Logger.info(
`onCreate for continuation sessionId: ${this.sessionId}`
)
this
.
contentStorage
=
new
ContenStorage
();
g_object.on("status", this.statusCallback);
// set session id, so it will sync data from remote device
g_object.setSessionId(this.sessionId);
this.contentStorage = new ContentStorage();
this.context.restoreWindowStage(this.contentStorage);
}
}
onContinue
(
wantParams
:
{[
key
:
string
]:
any
})
{
console
.
log
(
"
using distributedObject
"
)
this
.
sessionId
=
"
654321
"
;
g_object
.
setSessionId
(
this
.
sessionId
);
//1 设置分布式对象的session id
g_object
.
name
=
"
Amy
"
;
// 填入数据
wantParams
[
"
session
"
]
=
this
.
sessionId
;
// 将session id 通过want传到远端
return
true
;
}
```
以上完整的示例见sample
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录