合作咨询
我们的专家服务团队将竭诚为您提供专业的合作咨询服务
应用接续,指用户在一个设备上操作某个应用时,可以快速切换到另一个设备的相同应用,无缝衔接之前的应用体验。比如在用户使用过程中,使用情景发生了变化,之前使用的设备不再适合继续当前任务,或者周围有更合适的设备,此时用户可以选择使用新的设备来继续当前的任务。接续完成后,之前设备的应用可退出或保留,用户可以将注意力集中在被启动的设备上,继续执行任务。
如图所示,在手机上编辑备忘录,到办公室后切换到电脑上继续编辑,完成任务的无缝衔接。

HarmonyOS底层解决了应用接续过程中设备发现、连接、组网等过程繁琐的开发难点,应用在接入时仅需关注数据的传输和恢复,参考如下章节完成开发:
HarmonyOS NEXT Developer Preview0及以上版本的设备。
应用接续一般用于用户长时间停留的页面,默认情况下,应用接续完成后,源端应用会自动退出。开发者可以参考按需退出进行配置。
不同类型的应用建议的配置项如下:
垂类 | 场景 | 发起接续页面与接续同步内容 | 接续完成后,源端应用退出方案 |
|---|---|---|---|
工具 | 备忘录 | 备忘录详情页,备忘浏览进度同步。 | 退出 |
笔记 | 笔记编辑页,笔记浏览或编辑进度同步。 | 退出 | |
日历 | 任意页面,日期视图、日程浏览或日程编辑进度同步。 | 退出 | |
邮箱 | 邮件编辑页面,内容进度及附件同步。 | 退出 | |
浏览器 | 网页内容详情页,网页浏览进度同步。 | 退出 | |
出行导航 | 地图服务 | 路线查询、导航界面,当前路线及导航同步。 | 退出 |
影音娱乐 | 视频/短视频/微短剧/直播 | 音视频播放、直播页,音视频、直播播放进度同步。 | 应用按需适配 |
音乐/K歌/电台/乐器 | 音视频播放、直播页,音视频、直播播放进度同步。 | 应用按需适配 | |
儿童 | 早教/儿歌 | 音视频播放、直播页,音视频、直播播放进度同步。 | 应用按需适配 |
新闻阅读 | 听书/有声读物/电子书/小说/杂志 | 书籍首页、小说阅读、听书页,阅读及听书进度同步。 | 退出,但若涉及较多听书或直播类场景,可不退出仅暂停(听书)、不退出且不暂停(直播)。 |
新闻 | 新闻详情页,新闻浏览进度同步。 | 退出 | |
办公
| 会议 | 会议界面,当前会议同步。 | 不退出应用,仅退出会议,可返回聊天框界面。 |
设计 | CAD编辑界面,编辑内容同步。 | 应用按需适配 | |
社交通讯 | 社交媒体平台 | 图文浏览、视频浏览、编辑页,浏览及编辑进度同步。 | 应用按需适配 |
拍摄美化 | 拍摄美化/图像美化 | 图片、视频编辑页,编辑内容及进度同步。 | 退出 |
便捷生活
| 租房买房/家居装修 | 应用按需适配 | 退出 |
菜谱/烘焙/饮食/食谱 | 应用按需适配 | 退出 | |
种草 | 应用按需适配 | 退出 | |
金融理财 | 股票/股票行情/基金/证券/证券投资咨询 | 应用按需适配 | 退出 |
游戏 | 游戏 | 应用按需适配 | 退出 |

以下为实现应用接续的主要接口,详细的接口说明可查阅UIAbility接口文档。
接口名 | 描述 |
|---|---|
onContinue(wantParam : {[key: string]: Object}): OnContinueResult | 接续源端在该回调中保存迁移所需数据,并返回是否同意迁移:
|
onCreate(want: Want, param: AbilityConstant.LaunchParam): void; | 接续目的端为冷启动或多实例应用热启动时,在该回调中完成数据恢复,并触发页面恢复。 |
onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; | 接续目的端为单实例应用热启动时,在该回调中完成数据恢复,并触发页面恢复。 |
在module.json5文件的abilities中,将continuable标签配置为“true”,表示该UIAbility可被迁移。默认值为false,将被系统识别为无法迁移。
{
"module": {
// ...
"abilities": [
{
// ...
"continuable": true,
// ...
}
],
// ...
}
}根据业务需要配置应用启动模式类型,配置详情请参照UIAbility组件启动模式。
当应用触发迁移时,onContinue()接口在源端被调用,开发者可以在该接口中保存迁移数据,实现应用兼容性检测,决定是否支持此次迁移。
如果迁移过程中的兼容性问题对于应用迁移体验影响较小或无影响,可以跳过该步骤。
字段 | 含义 |
|---|---|
version | 对端应用的版本号 |
targetDevice | 对端设备的networkId |
export default class EntryAbility extends UIAbility {
// Indicates whether target side should restore Router page stack automatically.
// ...
onContinue(wantParam: Record<string, Object>) {
// Read target app version to guard cross-version continuation compatibility.
const targetVersion = wantParam.version;
// Define minimum compatible version supported by the source app.
const versionThreshold: number = 1000;
// Reject continuation when target side is below required version.
if (targetVersion < versionThreshold) {
// Give user-friendly reason when continuation is rejected.
try {
this.context.windowStage.getMainWindowSync()
.getUIContext()
.getPromptAction()
.showToast({
message: '目标端应用版本号过低,不支持接续,请您升级应用版本后再试',
duration: 2000
})
} catch (error) {
hilog.error(DOMAIN, 'testTag', 'Failed to getMainWindowSync. Cause: %{public}s', JSON.stringify(error));
}
// Return MISMATCH to terminate continuation negotiation.
return AbilityConstant.OnContinueResult.MISMATCH;
}
// Put migration payload into want params for target-side restore.
const continueInput = AppStorage.get('entryAbilityContext') as string;
if (continueInput) {
// Custom field "data" carries text payload.
wantParam['data'] = continueInput;
}
// ...
return AbilityConstant.OnContinueResult.AGREE;
}
// ...
}在Stage模型中,应用在不同启动模式下将调用不同的接口,以恢复数据、加载界面。不同情况下的函数调用如下图所示:

在对端设备UIAbility中实现onCreate()与onNewWant()接口,恢复迁移数据。
export default class EntryAbility extends UIAbility {
// Indicates whether target side should restore Router page stack automatically.
// ...
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
try {
// Keep system color mode unmanaged by the app.
// ...
if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {
// Restore migration payload and stack snapshot from continuation parameters.
this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {
});
if (want.parameters !== undefined) {
if (typeof want.parameters.data === 'string') {
AppStorage.setOrCreate('entryAbilityContext', want.parameters.data);
}
// ...
}
// Restore window stage so UI can reconstruct previous continuation state.
this.context.restoreWindowStage(new LocalStorage());
}
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
}
// ...
}接口restoreWindowStage(this.storage)必须在同步接口方法中执行,如果在异步回调中执行,可能会导致应用迁移后页面加载失败。
一般情况下,跨端迁移的双端是同Ability之间,但有些应用在不同设备类型下的同一个业务Ability名称不同(即异Ability),为了支持该场景下的两个Ability之间能够完成迁移,可以通过在module.json5文件的abilities标签中配置迁移类型continueType进行关联。 需要迁移的两个Ability的continueType字段取值必须保持一致,示例如下:
设备A:
{
"module": {
// ...
"abilities": [
{
// ...
"continuable": true,
"continueType": ['continueType1'],
}
],
// ...
}
}设备B:
{
"module": {
// ...
"abilities": [
{
// ...
"continuable": true,
"continueType": ['continueType1']
}
],
// ...
}
}同一开发者名下的某款应用,可能在不同设备类型上使用了不同的BundleName。如果该应用需要支持跨端迁移,则需要在该应用的不同Bundle对应的module.json5配置文件中进行如下配置:
示例如下:
不同BundleName的相同应用在设备A和设备B之间相互迁移,设备A应用的BundleName为com.demo.example1,设备B应用的BundleName为com.demo.example2。
{
"module": {
// ...
"abilities": [
{
"name": "EntryAbility"
// ...
"continueType": ['continueType'],
"continueBundleName": ["com.demo.example2"],
}
]
}
} 在设备B的应用配置文件中,continueBundleName字段配置包含设备A上应用的BundleName,com.demo.example1为设备A上应用的BundleName。
{
"module": {
// ...
"abilities": [
{
"name": "EntryAbility"
// ...
"continueType": ['continueType'],
"continueBundleName": ["com.demo.example1"],
}
]
}
} 某款应用在不同类型的设备上,可能会由不同的开发者发布。在这种场景下,如果该应用需要支持跨端迁移,则需要在AppGallery Connect平台申请“接续服务” 。
下面以同一应用对应2个开发者为例进行介绍操作步骤。假设手机应用A与PC应用B分别属于不同开发者,应用A的APP ID 为 AppId_A,应用B的APP ID为AppId_B。
操作步骤中的界面截图在不同版本中可能存在差异,请以实际网站效果为准。

应用接续支持配置多个不同的AppID,配置顺序决定了在接续目标端设备上匹配应用的顺序。填写对应设备类型的AppID时务必包含自己的AppID。
AppID配置次序建议如下:
应用接续发起端 | 应用接续目标端 | 发起端A应用AppId配置优先次序(从高到低) |
|---|---|---|
移动端 | TV端/PC端 | ① TV版A应用AppID ② PC版A应用AppID ③ 移动版A应用AppID |
TV端 | PC端/移动端 | ① PC版A应用AppID ② TV版A应用AppID ③ 移动版A应用AppID |
PC端 | TV端/移动端 | ① TV版A应用AppID ② PC版A应用AppID ③ 移动版A应用AppID |




{
"module": {
// ...
"abilities": [
{
"name": "EntryAbility"
// ...
"continueType": ['continueType'],
"continueBundleName": ["com.demo.example2"],
}
]
}
} 在设备B的应用配置文件中,continueBundleName字段配置包含设备A上应用的BundleName,com.demo.example1为设备A上应用的BundleName。
// In the configuration file on device B, the continueBundleName field contains the BundleName of the app on device A.
{
"module": {
// ...
"abilities": [
{
"name": "EntryAbility"
// ...
"continueType": ['continueType'],
"continueBundleName": ["com.demo.example1"],
}
]
}
} {
"module": {
// ...
"abilities": [
{
// ...
"name": "EntryAbility"
"continueType": ['EntryAbility_ContinueQuickStart'],
}
]
}
} 配置了快速启动的应用,在用户发起接续时会立即收到一次launchReason为提前拉起(PREPARE_CONTINUATION)的onCreate()/onNewWant()请求,随后再收到一次launchReason为接续拉起(CONTINUATION)的onNewWant()请求。如下所示:
场景 | 生命周期函数 | launchParam.launchReason |
|---|---|---|
第一次启动请求 | onCreate (冷启动) 或 onNewWant (热启动) | AbilityConstant.LaunchReason.PREPARE_CONTINUATION |
第二次启动请求 | onNewWant | AbilityConstant.LaunchReason.CONTINUATION |

如果没有配置快速启动,则触发迁移时只会收到一次启动请求:
场景 | 生命周期函数 | launchParam.launchReason |
|---|---|---|
一次启动请求 | onCreate (冷启动) 或 onNewWant (热启动) | AbilityConstant.LaunchReason.CONTINUATION |
配置快速启动后,对应的onCreate()/onNewWant()接口实现可参考如下示例:
export default class EntryAbility extends UIAbility {
// ...
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
try {
// ...
if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {
// Restore migration payload and stack snapshot from continuation parameters.
this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {
});
// ...
// Restore window stage so UI can reconstruct previous continuation state.
this.context.restoreWindowStage(new LocalStorage());
}
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
try {
// Keep system color mode unmanaged by the app.
// ...
if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {
// Restore migration payload and stack snapshot from continuation parameters.
this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {
hilog.info(DOMAIN, 'testTag', 'setMissionContinueState');
});
// ...
// Restore window stage so UI can reconstruct previous continuation state.
this.context.restoreWindowStage(new LocalStorage());
}
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onNewWant');
// ...
}
// ...
}
从API version 10起,提供了支持动态配置迁移能力的功能。即应用可以根据实际使用场景,在需要迁移功能时,设置开启应用迁移能力;在业务不需要迁移时,则可以关闭迁移能力。开发者可以通过调用setMissionContinueState()接口对迁移能力进行设置。
接口状态值 | 含义 |
|---|---|
AbilityConstant.ContinueState.ACTIVE | 应用当前可迁移能力开启 |
AbilityConstant.ContinueState.INACTIVE | 应用当前可迁移能力关闭 |
设置迁移能力的时机
默认状态下,应用的迁移能力为ACTIVE状态,即可以迁移。
如果需要实现某些特殊场景,比如只在具体某个页面下支持迁移,或者只在某个事件发生时才支持迁移,可以按照如下步骤进行配置。
private setContinueEnabled(isOn: boolean): void {
const state = isOn ? AbilityConstant.ContinueState.ACTIVE : AbilityConstant.ContinueState.INACTIVE;
this.context.setMissionContinueState(state, (result) => {
hilog.info(0x0000, `setMissionContinueState ${state} result: `, JSON.stringify(result));
});
}
aboutToAppear() {
// Ensure continuation is active when this page is visible.
this.setContinueEnabled(true);
}Toggle({ type: ToggleType.Switch, isOn: true })
.selectedColor($r('sys.color.icon_emphasize'))
.switchPointColor(Color.White)
.onChange((isOn: boolean) => {
// Sync ability continuation state with UI switch.
this.setContinueEnabled(isOn);
})保证迁移连续性
由于迁移加载时,对端启动的应用可能执行过自己的迁移状态设置命令(如:冷启动时目标端在onCreate()中设置了INACTIVE;热启动时对端已打开了不可迁移的页面,迁移状态为INACTIVE等情况)。为了保证迁移过后的应用依然具有可以迁移回源端的能力,应在onCreate()和onNewWant()的迁移调用判断中,将迁移状态设置为ACTIVE。
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
try {
// ...
if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {
// Restore migration payload and stack snapshot from continuation parameters.
this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {
});
// ...
// Restore window stage so UI can reconstruct previous continuation state.
this.context.restoreWindowStage(new LocalStorage());
}
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
try {
// Keep system color mode unmanaged by the app.
// ...
if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {
// Restore migration payload and stack snapshot from continuation parameters.
this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {
hilog.info(DOMAIN, 'testTag', 'setMissionContinueState');
});
// ...
// Restore window stage so UI can reconstruct previous continuation state.
this.context.restoreWindowStage(new LocalStorage());
}
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onNewWant');
// ...
}支持应用动态选择是否进行页面栈恢复(默认进行页面栈信息恢复)。如果应用不想使用系统默认恢复的页面栈,则可以设置不进行页面栈迁移,而需要在onWindowStageRestore()设置迁移后进入的页面,参数定义见Params中的SUPPORT_CONTINUE_PAGE_STACK_KEY。
应用在源端的页面栈中存在Index和Second路由,而在对端恢复时不需要按照源端页面栈进行恢复,需要恢复到指定页面。
onContinue(wantParam: Record<string, Object>) {
// ...
wantParam[wantConstant.Params.SUPPORT_CONTINUE_PAGE_STACK_KEY] = AppStorage.get('ifContinueRouterPage') as boolean;
// Return AGREE to allow continuation process to proceed.
return AbilityConstant.OnContinueResult.AGREE;
}export default class EntryAbility extends UIAbility {
// Indicates whether target side should restore Router page stack automatically.
SUPPORT_CONTINUE_PAGE_STACK_KEY: boolean = true;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
try {
// ...
if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {
// Restore migration payload and stack snapshot from continuation parameters.
this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {
});
if (want.parameters !== undefined) {
// ...
if (typeof want.parameters['ohos.extra.param.key.supportContinuePageStack'] === 'boolean') {
this.SUPPORT_CONTINUE_PAGE_STACK_KEY =
want.parameters['ohos.extra.param.key.supportContinuePageStack'] as boolean;
}
}
// Restore window stage so UI can reconstruct previous continuation state.
this.context.restoreWindowStage(new LocalStorage());
}
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
}
// ...
}onWindowStageRestore(windowStage: window.WindowStage) {
// If Router stack migration is disabled, force fallback landing page.
if (!this.SUPPORT_CONTINUE_PAGE_STACK_KEY) {
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
return;
}
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
});
}
}支持应用动态选择迁移成功后是否退出迁移源端应用(默认迁移成功后退出迁移源端应用)。如果应用不想让系统自动退出迁移源端应用,则可以设置不退出,参数定义见Params中的SUPPORT_CONTINUE_SOURCE_EXIT_KEY。
示例:应用迁移设置迁移成功后不退出迁移源端应用
onContinue(wantParam: Record<string, Object>) {
// ...
// Export Router/source-exit switches for target-side behavior control.
wantParam[wantConstant.Params.SUPPORT_CONTINUE_SOURCE_EXIT_KEY] =
AppStorage.get('entryAbilityContinueExit') as boolean;
// ...
return AbilityConstant.OnContinueResult.AGREE;
}问题描述
系统浏览器等系统应用打开后对端设备也不出现接续图标。
解决方案
在打开系统浏览器、已有内容的备忘录笔记界面或新开发的应用界面后,对端均未出现接续图标,可以按照以下步骤进行排查:
hidumper -s 4700 -a "buscenter -l remote_device_info"
执行完成后,RemoteDeviceInfo中列出的设备即为已成功与当前设备组网的设备。如下图所示,该设备已与两台其他设备成功组网。

问题描述
1分钟以上无任何操作,图标将自动消失;再次操作应用时,图标将重新出现。
问题解释
图标显隐是系统的一项特性。根据当前的策略,图标在源端最后一次触屏操作后的1分钟内保持显示。如果超过1分钟没有进行任何操作,图标将自动隐藏,以减少对用户的干扰。同样地,当锁屏时,图标将在10秒后自动消失,这也是系统正常运行的一部分。
问题描述
系统浏览器等系统应用正常出现接续图标,新接入的应用无法出现接续图标。
解决方案
仅当应用配置了continuable标签,并且处于获焦且可接续状态时,才会发送接续广播,使得对端显示接续图标。可以按照以下步骤排查: