Qt for HarmonyOS/user development/application continuation guild zh: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Created page with "== 简介 == HarmonyOS 平台支持多进程架构,Qt 通过 '''startNoUiChildProcess''' API 为开发者提供了创建无 UI 子进程并传递启动参数的能力。本指南将详细说明该功能的使用方法、部署步骤,并提供完整的代码示例。 == 功能架构概述 == 在 HarmonyOS 中使用 Qt 子进程功能时,可以参考以下架构原则: * '''主应用进程''' ** 负责 UI 交互和用户界面 ** 通过 QtOhosExtras 模块调...")
 
No edit summary
Line 1: Line 1:
= Qt for HarmonyOS 应用接续开发指南 =
== 简介 ==
== 简介 ==
本文面向 Qt 开发者,介绍如何在 HarmonyOS 上实现“应用接续”(跨设备迁移应用状态)。


HarmonyOS 平台支持多进程架构,Qt 通过 '''startNoUiChildProcess''' API 为开发者提供了创建无 UI 子进程并传递启动参数的能力。本指南将详细说明该功能的使用方法、部署步骤,并提供完整的代码示例。
QtOhosExtras 模块已封装 HarmonyOS 的 onContinue / onNewWant 等流程,开发者仅需使用 Qt 接口完成迁移请求、数据封装与目标端恢复。
 
== 功能架构概述 ==
 
在 HarmonyOS 中使用 Qt 子进程功能时,可以参考以下架构原则:


* '''主应用进程'''
----
** 负责 UI 交互和用户界面
** 通过 QtOhosExtras 模块调用子进程 API
** 传递启动参数给子进程
* '''子进程(无 UI)'''
** 接收主进程传递的启动参数
** 执行后台任务和数据处理
** 独立运行,不依赖主进程 UI


=== 核心特性 ===
== 能力与模块 ==


Qt for HarmonyOS 的子进程功能具有以下特点:
=== 能力 ===
* 在设备间迁移当前应用状态
* 支持快速预热(ContinueQuickStart)
* 支持源端保留 / 退出策略控制


# '''多参数传递支持''':应用可以自定义传递多个启动参数,参数类型为基础类型。
=== 模块 ===
# '''差异化启动能力''':支持启动不同的子进程时传递不同的启动参数。
* 模块名:<code>qtohosextras</code>
# '''无 UI 后台处理''':子进程专门用于后台处理任务,不占用 UI 资源。
* 核心类:
# '''参数自动转发''':启动参数会自动转发到子进程的 <code>main()</code> 函数。
** <code>QOhosAbilityContext</code>
** <code>QOhosOnContinueContext</code>
** <code>QOhosWantInfo</code>
* 工具函数:
** <code>QtOhosExtras::tryGetOnContinueData</code>


== API 详解 ==
=== 数据通道限制 ===
* 小于 100KB:通过 Want parameters 携带
** 数据类型:Base64 的 <code>QByteArray</code>
** 键名:<code>__io_qt_on_continue_migration_data</code>
* 大于 100KB:Qt 暂未实现,将在后续版本提供


=== startNoUiChildProcess 函数 ===
----


该函数是 Qt for HarmonyOS 提供的核心子进程启动 API:
== 工作流程 ==


<source lang="cpp">
# 源端收到迁移请求(<code>continueRequestReceived</code>)
static void QtOhosExtras::QOhosAppContext::startNoUiChildProcess(
#* 序列化业务状态(<100KB)
    QString libraryName,
#* 同意 / 拒绝 / 版本不匹配响应
    QStringList args
#* 按需决定源端是否退出
);
# 目标端收到 Want(冷启动或热启动)
</source>
#* 使用 <code>tryGetOnContinueData()</code> 提取迁移数据
#* 反序列化并恢复 UI 状态
# 可选能力
#* 配置 ContinueQuickStart 快速预热
#* 动态开关迁移能力
#* 控制源端保留 / 退出策略


==== 参数详解 ====
----


== 核心 API 速览 ==
{| class="wikitable"
{| class="wikitable"
! 参数 !! 类型 !! 说明
! API / 信号 !! 说明
|-
| <code>QOhosAbilityContext::continueRequestReceived</code> || 源端接收迁移请求的信号
|-
| <code>QOhosOnContinueContext</code> || 同意/拒绝/版本不匹配响应;设置源端退出策略
|-
| <code>QOhosAbilityContext::newWantInfoReceived</code> || 目标端运行时接收新 Want 的信号
|-
| <code>QOhosWantInfo::launchReason()</code> || 启动原因:StartAbility / PrepareContinuation / Continuation
|-
|-
| <code>libraryName</code> || QString || 子进程的动态库名称(如 <code>"libChildApp.so"</code>)
| <code>QtOhosExtras::tryGetOnContinueData(const QOhosWant &want)</code> || 提取迁移数据(返回 <code>QSharedPointer&lt;QByteArray&gt;</code>)
|-
|-
| <code>args</code> || QStringList || 要传递给子进程的参数列表
| <code>QOhosAbilityContext::setContinuationActive(bool)</code> || 动态开关迁移能力
|-
| <code>QOhosOnContinueContext::setExitAppOnSourceDeviceAfterMigration(bool)</code> || 控制源端迁移成功后是否退出
|}
|}


==== 功能机制 ====
----
 
该函数基于 HarmonyOS 的 [https://developer.huawei.com/consumer/en/doc/harmonyos-references-V5/js-apis-app-ability-childprocessmanager-V5 Child Process Manager API] 实现,具有以下特点:
 
# '''异步启动''':子进程启动为异步操作,不会阻塞主进程。
# '''参数转发''':传递的参数会被转发到子进程的 <code>main()</code> 函数中作为命令行参数。
# '''进程隔离''':子进程独立运行,与主进程内存空间隔离。
# '''生命周期管理''':子进程需要自行管理生命周期。
 
== 手动开发步骤 ==
 
=== 1. 准备工作 ===
 
首先,确保您有:
* Qt for HarmonyOS 开发环境
* HarmonyOS 应用工程目录
* 对多进程架构的基本理解
 
=== 2. 创建项目结构 ===
 
典型的子进程应用需要包含主应用和子进程两部分,建议按以下结构组织:
 
<pre>
YourProject/
├── MainApp/                # 主应用(负责UI交互)
│  ├── main.cpp
│  ├── mainwindow.cpp
│  ├── mainwindow.h
│  ├── mainwindow.ui
│  └── MainApp.pro
└── BackgroundTask/        # 子进程应用(后台任务处理)
    ├── main.cpp
    └── BackgroundTask.pro
</pre>
 
=== 3. 子进程实现详解 ===
 
==== 基础子进程框架 ====
 
子进程的核心任务是接收和处理主进程传递的启动参数。以下是一个完整的子进程实现:
 
'''BackgroundTask/main.cpp:'''
<source lang="cpp">
#include <QCoreApplication>
#include <QDebug>
 
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);


    qDebug() << "Child process started";
== 源端实现(发起迁移) ==
    qDebug() << "Total arguments:" << argc;


    // 处理传递的参数
=== 实现步骤 ===
    for (int i = 0; i < argc; ++i) {
# 监听迁移请求:<code>continueRequestReceived</code>
        qDebug() << "Argument" << i << ":" << argv[i];
# 校验版本/业务条件:<code>ctx-&gt;sourceApplicationVersionCode()</code>
    }
# 序列化状态(<100KB)并响应:
#* 同意:<code>setAgreeResponse(serialized)</code>
#* 版本不匹配:<code>setMismatchResponse()</code>
#* 拒绝:<code>setRejectResponse()</code>
# 是否保留源端:
#* <code>setExitAppOnSourceDeviceAfterMigration(false)</code>(默认 true)
# 按需开/关迁移:
#* <code>setContinuationActive(bool)</code>


    // 根据参数执行不同的业务逻辑
=== 示例:同意迁移并保留源端 ===
     if (argc > 1) {
<syntaxhighlight lang="cpp">
         QString command = QString::fromLocal8Bit(argv[1]);
auto ability = QOhosAbilityContext::getInstanceForMainWindow(window.windowHandle());
         if (command == "task1") {
QObject::connect(ability.get(), &QOhosUiAbilityContext::continueRequestReceived,
             qDebug() << "Executing task 1";
     [](auto ctx) {
             // 执行任务1的逻辑
         auto appVersion = QOhosAppContext::instance()->getBundleInfo()->versionCode();
         } else if (command == "task2") {
         if (ctx->sourceApplicationVersionCode() == appVersion) {
             qDebug() << "Executing task 2";
             QByteArray payload = /* serialize state (<100KB) */;
            // 执行任务2的逻辑
            ctx->setAgreeResponse(payload);
             ctx->setExitAppOnSourceDeviceAfterMigration(false); // keep source
         } else {
             ctx->setMismatchResponse();
         }
         }
     }
     });
 
</syntaxhighlight>
    return app.exec();
}
</source>
 
=== 4. 主应用实现详解 ===
 
==== A. 界面头文件定义 ====
 
'''MainApp/mainwindow.h:'''
<source lang="cpp">
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
 
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
 
private slots:
    void startChildProcess1();
    void startChildProcess2();


private:
'''参考:''' <code>examples/qtohosextras/applicationcontinuation/main.cpp</code>
    Ui::MainWindow *ui;
};


#endif // MAINWINDOW_H
----
</source>


==== B. 核心功能实现 ====
== 目标端实现(接收与恢复) ==


'''MainApp/mainwindow.cpp:'''
=== 实现步骤 ===
<source lang="cpp">
# 冷启动获取:
#include "mainwindow.h"
#* <code>auto wantInfo = QOhosAppContext::getAppLaunchWantInfo();</code>
#include "ui_mainwindow.h"
# 运行时获取:
#include <QtOhosExtras/QtOhosExtras>
#* 监听 <code>QOhosAbilityContext::newWantInfoReceived</code>
#include <QStringList>
# 场景区分:
#* <code>launchReason()</code> == <code>PrepareContinuation</code>(预热)
#* <code>launchReason()</code> == <code>Continuation</code>(正式迁移数据)
# 提取数据:
#* <code>auto data = QtOhosExtras::tryGetOnContinueData(wantInfo-&gt;want());</code>
# 恢复状态:
#* 反序列化 <code>data</code>,还原业务状态并刷新 UI


MainWindow::MainWindow(QWidget *parent)
=== 示例:冷启动 + 热启动恢复 ===
     : QMainWindow(parent)
<syntaxhighlight lang="cpp">
     , ui(new Ui::MainWindow)
// Cold start
{
if (auto launchInfo = QOhosAppContext::getAppLaunchWantInfo()) {
    ui->setupUi(this);
     auto data = QtOhosExtras::tryGetOnContinueData(launchInfo->want());
     if (data) { /* deserialize and restore */ }
}
}


MainWindow::~MainWindow()
// Hot start
{
auto ability = QOhosAbilityContext::getInstanceForMainWindow(window.windowHandle());
     delete ui;
QObject::connect(ability.get(), &QOhosUiAbilityContext::newWantInfoReceived,
}
    [](const QSharedPointer<QOhosWantInfo> &info) {
        if (info->launchReason() == QOhosWantInfo::LaunchReason::Continuation) {
            auto data = QtOhosExtras::tryGetOnContinueData(info->want());
            if (data) { /* deserialize and restore */ }
        }
     });
</syntaxhighlight>


void MainWindow::startChildProcess1()
----
{
    // 启动子进程并传递参数
    QtOhosExtras::QOhosAppContext::startNoUiChildProcess(
        "libBackgroundTask.so",
        QStringList{
            "task1",          // 任务类型
            "param1",          // 参数1
            "param2",          // 参数2
            "priority_high"    // 优先级
        });


    ui->statusLabel->setText("Child Process 1 Started!");
== 快速预热(ContinueQuickStart) ==
}


void MainWindow::startChildProcess2()
=== 适用场景 ===
{
希望目标端先拉起/预热,数据到达后再恢复业务状态。
    // 启动另一个子进程实例,传递不同参数
    QtOhosExtras::QOhosAppContext::startNoUiChildProcess(
        "libBackgroundTask.so",
        QStringList{
            "task2",          // 不同的任务类型
            "config.json",    // 配置文件
            "debug_mode"      // 调试模式
        });


    ui->statusLabel->setText("Child Process 2 Started!");
=== 配置方式 ===
}
在 <code>module.json5</code> 中,将目标 Ability 的 <code>continueType</code> 末尾添加:
</source>
* <code>_ContinueQuickStart</code>


==== C. 主应用项目配置 ====
=== 流程说明 ===
* 首先触发 <code>PrepareContinuation</code>(预热)
* 随后触发 <code>Continuation</code>(正式数据)


'''MainApp/MainApp.pro:'''
=== 示例:区分预热/正式 ===
<source lang="pro">
<syntaxhighlight lang="cpp">
QT += core gui widgets ohosextras
QObject::connect(ability.get(), &QOhosUiAbilityContext::newWantInfoReceived,
    [](const QSharedPointer<QOhosWantInfo> &info) {
        switch (info->launchReason()) {
        case QOhosWantInfo::LaunchReason::PrepareContinuation:
            // Warm-up / placeholder
            break;
        case QOhosWantInfo::LaunchReason::Continuation: {
            auto data = QtOhosExtras::tryGetOnContinueData(info->want());
            if (data) { /* deserialize and restore */ }
            break;
        }
        default:
            break;
        }
    });
</syntaxhighlight>


SOURCES += \
----
    main.cpp \
    mainwindow.cpp


HEADERS += \
== 动态开关迁移 ==
    mainwindow.h


FORMS += \
=== 适用场景 ===
    mainwindow.ui
特定页面不允许迁移时关闭,需要迁移前再开启。
</source>


== 手动编译和部署 ==
=== 接口 ===
<code>QOhosAbilityContext::setContinuationActive(bool)</code>(默认开启)


=== 1. 编译子进程动态库 ===
=== 示例 ===
<syntaxhighlight lang="cpp">
auto ability = QOhosAbilityContext::getInstanceForMainWindow(window.windowHandle());
ability->setContinuationActive(false); // disable
ability->setContinuationActive(true);  // enable when needed
</syntaxhighlight>


<source lang="bash">
----
# 进入子进程目录
cd BackgroundTask


# 生成 Makefile
== 源端退出策略 ==
qmake BackgroundTask.pro


# 编译生成 .so 文件
=== 说明 ===
make
默认情况下,迁移成功后系统会关闭源端;调试或需要保留源端时可将其设置为 false。


# 验证生成的文件
=== 接口 ===
ls -la libBackgroundTask.so
<code>QOhosOnContinueContext::setExitAppOnSourceDeviceAfterMigration(bool)</code>
</source>


=== 2. 手动部署动态库文件 ===
=== 示例:同意迁移但保留源端 ===
 
<syntaxhighlight lang="cpp">
在 HarmonyOS 中部署子进程动态库时,需要遵循特定的目录结构:
QObject::connect(ability.get(), &QOhosUiAbilityContext::continueRequestReceived,
 
    [](auto ctx) {
<source lang="bash">
        auto appVersion = QOhosAppContext::instance()->getBundleInfo()->versionCode();
# 创建目标目录(如果不存在)
        if (ctx->sourceApplicationVersionCode() == appVersion) {
mkdir -p entry/libs/arm64-v8a
            ctx->setAgreeResponse(QByteArray("Migration Test Data"));
 
            ctx->setExitAppOnSourceDeviceAfterMigration(false);
# 复制动态库到指定位置
        } else {
cp BackgroundTask/libBackgroundTask.so entry/libs/arm64-v8a/
            ctx->setMismatchResponse();
 
        }
# 验证部署
    });
ls -la entry/libs/arm64-v8a/libBackgroundTask.so
</syntaxhighlight>
</source>
 
=== 3. 编译主应用 ===
 
<source lang="bash">
# 编译主应用
cd MainApp
qmake MainApp.pro
make
</source>
 
=== 完整部署检查清单 ===
 
<pre>
ohostemplateforqtapplication/
├── entry/
│  └── libs/
│      └── arm64-v8a/
│          ├── libBackgroundTask.so  # 子进程动态库
│          └── ... # 其他Qt相关库文件
├── MainApp/
└── BackgroundTask/
</pre>
 
== 测试验证方法 ==
 
=== 1. 功能测试 ===


# '''启动主应用''':运行编译好的主应用程序。
----
# '''触发子进程''':点击界面上的启动按钮。
# '''观察状态反馈''':检查应用界面的状态提示信息。


=== 2. 进程状态验证 ===
== 快速上手清单 ==


通过以下方式确认进程创建成功:
# 源端:监听 <code>continueRequestReceived</code>,序列化数据 <100KB,调用 <code>setAgreeResponse</code> 或 mismatch/reject;按需设置退出策略与迁移开关。
# 目标端:通过 <code>launchReason()</code> 判定预热/正式;使用 <code>tryGetOnContinueData</code> 提取并恢复状态。
# 需要预热:配置 <code>continueType</code> 为 <code>_ContinueQuickStart</code>,在 <code>PrepareContinuation</code> 只做轻量处理。


==== 任务管理器检查 ====
----
在设备的任务管理器中应该能看到:
* '''主进程''':<code>com.yourpackage.name</code>
* '''子进程''':<code>com.yourpackage.name:QChildProcess0</code>


=== 完整测试案例 ===
== 参考路径 ==


以下是基于 <code>testUiLessProcess</code> 参考示例的完整测试流程:
* 示例:<code>qtohosextras/examples/qtohosextras/applicationcontinuation/main.cpp</code>
* 实现:<code>qtohosextras/src/ohosextras/qohosabilitycontext.cpp/.h</code>
* Want 定义:<code>qtohosextras/src/ohosextras/qohoswant.h</code>


# 编译子进程
----
#: <source lang="bash">cd testUiLessProcess/TestConsoleApp && qmake TestConsoleApp.pro && make</source>
# 部署动态库
#: <source lang="bash">cp libTestConsoleApp.so ../ohostemplateforqtapplication/entry/libs/arm64-v8a/</source>
# 编译运行主应用
#: <source lang="bash">cd ../mainWindowApp && qmake mainWindowApp.pro && make && ./mainWindowApp</source>
# 执行测试操作
#* 点击 "Start Child Process" 按钮。
#* 观察到 "Start UI less Child Process Successfully!" 提示。
# 验证结果
#* 任务管理器查看进程。


== 相关资源 ==
== 注意事项 ==


=== 官方文档 ===
* 未响应迁移请求默认视为拒绝,请在回调中明确处理。
* [https://developer.huawei.com/consumer/en/doc/harmonyos-references-V5/js-apis-app-ability-childprocessmanager-V5 HarmonyOS Child Process Manager API] - 底层 API 参考
* 回调在 Qt 线程执行,避免跨线程操作 UI。
* 迁移数据需向前兼容,协议变更时携带版本并做好容错。
* Qt 暂未支持大于 100KB 数据的接续,将在未来版本中提供。
* 更多说明参考:HarmonyOS 应用接续官方指南(外部链接)

Revision as of 07:07, 25 December 2025

Qt for HarmonyOS 应用接续开发指南

简介

本文面向 Qt 开发者,介绍如何在 HarmonyOS 上实现“应用接续”(跨设备迁移应用状态)。

QtOhosExtras 模块已封装 HarmonyOS 的 onContinue / onNewWant 等流程,开发者仅需使用 Qt 接口完成迁移请求、数据封装与目标端恢复。


能力与模块

能力

  • 在设备间迁移当前应用状态
  • 支持快速预热(ContinueQuickStart)
  • 支持源端保留 / 退出策略控制

模块

  • 模块名:
    qtohosextras
    
  • 核心类:
    • QOhosAbilityContext
      
    • QOhosOnContinueContext
      
    • QOhosWantInfo
      
  • 工具函数:
    • QtOhosExtras::tryGetOnContinueData
      

数据通道限制

  • 小于 100KB:通过 Want parameters 携带
    • 数据类型:Base64 的
      QByteArray
      
    • 键名:
      __io_qt_on_continue_migration_data
      
  • 大于 100KB:Qt 暂未实现,将在后续版本提供

工作流程

  1. 源端收到迁移请求(
    continueRequestReceived
    
    • 序列化业务状态(<100KB)
    • 同意 / 拒绝 / 版本不匹配响应
    • 按需决定源端是否退出
  2. 目标端收到 Want(冷启动或热启动)
    • 使用
      tryGetOnContinueData()
      
      提取迁移数据
    • 反序列化并恢复 UI 状态
  3. 可选能力
    • 配置 ContinueQuickStart 快速预热
    • 动态开关迁移能力
    • 控制源端保留 / 退出策略

核心 API 速览

API / 信号 说明
QOhosAbilityContext::continueRequestReceived
源端接收迁移请求的信号
QOhosOnContinueContext
同意/拒绝/版本不匹配响应;设置源端退出策略
QOhosAbilityContext::newWantInfoReceived
目标端运行时接收新 Want 的信号
QOhosWantInfo::launchReason()
启动原因:StartAbility / PrepareContinuation / Continuation
QtOhosExtras::tryGetOnContinueData(const QOhosWant &want)
提取迁移数据(返回
QSharedPointer&lt;QByteArray&gt;
QOhosAbilityContext::setContinuationActive(bool)
动态开关迁移能力
QOhosOnContinueContext::setExitAppOnSourceDeviceAfterMigration(bool)
控制源端迁移成功后是否退出

源端实现(发起迁移)

实现步骤

  1. 监听迁移请求:
    continueRequestReceived
    
  2. 校验版本/业务条件:
    ctx-&gt;sourceApplicationVersionCode()
    
  3. 序列化状态(<100KB)并响应:
    • 同意:
      setAgreeResponse(serialized)
      
    • 版本不匹配:
      setMismatchResponse()
      
    • 拒绝:
      setRejectResponse()
      
  4. 是否保留源端:
    • setExitAppOnSourceDeviceAfterMigration(false)
      
      (默认 true)
  5. 按需开/关迁移:
    • setContinuationActive(bool)
      

示例:同意迁移并保留源端

auto ability = QOhosAbilityContext::getInstanceForMainWindow(window.windowHandle());
QObject::connect(ability.get(), &QOhosUiAbilityContext::continueRequestReceived,
    [](auto ctx) {
        auto appVersion = QOhosAppContext::instance()->getBundleInfo()->versionCode();
        if (ctx->sourceApplicationVersionCode() == appVersion) {
            QByteArray payload = /* serialize state (<100KB) */;
            ctx->setAgreeResponse(payload);
            ctx->setExitAppOnSourceDeviceAfterMigration(false); // keep source
        } else {
            ctx->setMismatchResponse();
        }
    });

参考:

examples/qtohosextras/applicationcontinuation/main.cpp

目标端实现(接收与恢复)

实现步骤

  1. 冷启动获取:
    • auto wantInfo = QOhosAppContext::getAppLaunchWantInfo();
      
  2. 运行时获取:
    • 监听
      QOhosAbilityContext::newWantInfoReceived
      
  3. 场景区分:
    • launchReason()
      
      ==
      PrepareContinuation
      
      (预热)
    • launchReason()
      
      ==
      Continuation
      
      (正式迁移数据)
  4. 提取数据:
    • auto data = QtOhosExtras::tryGetOnContinueData(wantInfo-&gt;want());
      
  5. 恢复状态:
    • 反序列化
      data
      
      ,还原业务状态并刷新 UI

示例:冷启动 + 热启动恢复

// Cold start
if (auto launchInfo = QOhosAppContext::getAppLaunchWantInfo()) {
    auto data = QtOhosExtras::tryGetOnContinueData(launchInfo->want());
    if (data) { /* deserialize and restore */ }
}

// Hot start
auto ability = QOhosAbilityContext::getInstanceForMainWindow(window.windowHandle());
QObject::connect(ability.get(), &QOhosUiAbilityContext::newWantInfoReceived,
    [](const QSharedPointer<QOhosWantInfo> &info) {
        if (info->launchReason() == QOhosWantInfo::LaunchReason::Continuation) {
            auto data = QtOhosExtras::tryGetOnContinueData(info->want());
            if (data) { /* deserialize and restore */ }
        }
    });

快速预热(ContinueQuickStart)

适用场景

希望目标端先拉起/预热,数据到达后再恢复业务状态。

配置方式

module.json5

中,将目标 Ability 的

continueType

末尾添加:

  • _ContinueQuickStart
    

流程说明

  • 首先触发
    PrepareContinuation
    
    (预热)
  • 随后触发
    Continuation
    
    (正式数据)

示例:区分预热/正式

QObject::connect(ability.get(), &QOhosUiAbilityContext::newWantInfoReceived,
    [](const QSharedPointer<QOhosWantInfo> &info) {
        switch (info->launchReason()) {
        case QOhosWantInfo::LaunchReason::PrepareContinuation:
            // Warm-up / placeholder
            break;
        case QOhosWantInfo::LaunchReason::Continuation: {
            auto data = QtOhosExtras::tryGetOnContinueData(info->want());
            if (data) { /* deserialize and restore */ }
            break;
        }
        default:
            break;
        }
    });

动态开关迁移

适用场景

特定页面不允许迁移时关闭,需要迁移前再开启。

接口

QOhosAbilityContext::setContinuationActive(bool)

(默认开启)

示例

auto ability = QOhosAbilityContext::getInstanceForMainWindow(window.windowHandle());
ability->setContinuationActive(false); // disable
ability->setContinuationActive(true);  // enable when needed

源端退出策略

说明

默认情况下,迁移成功后系统会关闭源端;调试或需要保留源端时可将其设置为 false。

接口

QOhosOnContinueContext::setExitAppOnSourceDeviceAfterMigration(bool)

示例:同意迁移但保留源端

QObject::connect(ability.get(), &QOhosUiAbilityContext::continueRequestReceived,
    [](auto ctx) {
        auto appVersion = QOhosAppContext::instance()->getBundleInfo()->versionCode();
        if (ctx->sourceApplicationVersionCode() == appVersion) {
            ctx->setAgreeResponse(QByteArray("Migration Test Data"));
            ctx->setExitAppOnSourceDeviceAfterMigration(false);
        } else {
            ctx->setMismatchResponse();
        }
    });

快速上手清单

  1. 源端:监听
    continueRequestReceived
    
    ,序列化数据 <100KB,调用
    setAgreeResponse
    
    或 mismatch/reject;按需设置退出策略与迁移开关。
  2. 目标端:通过
    launchReason()
    
    判定预热/正式;使用
    tryGetOnContinueData
    
    提取并恢复状态。
  3. 需要预热:配置
    continueType
    
    _ContinueQuickStart
    
    ,在
    PrepareContinuation
    
    只做轻量处理。

参考路径

  • 示例:
    qtohosextras/examples/qtohosextras/applicationcontinuation/main.cpp
    
  • 实现:
    qtohosextras/src/ohosextras/qohosabilitycontext.cpp/.h
    
  • Want 定义:
    qtohosextras/src/ohosextras/qohoswant.h
    

注意事项

  • 未响应迁移请求默认视为拒绝,请在回调中明确处理。
  • 回调在 Qt 线程执行,避免跨线程操作 UI。
  • 迁移数据需向前兼容,协议变更时携带版本并做好容错。
  • Qt 暂未支持大于 100KB 数据的接续,将在未来版本中提供。
  • 更多说明参考:HarmonyOS 应用接续官方指南(外部链接)