Qt for HarmonyOS/user development guide/application lifecycle guide
English 中文
Prerequisite Knowledge
HarmonyOS application lifecycle-related documentation:
Application Lifecycle (Stage Model)
UIAbilityContext API Reference
Qt for HarmonyOS Application Lifecycle Overview
In the HarmonyOS system, application lifecycle management follows the Stage model, primarily involving the lifecycle management of UIAbility components. Qt for HarmonyOS applications, as part of the HarmonyOS ecosystem, must adapt to this lifecycle model.
The lifecycle of Qt for HarmonyOS applications mainly involves the following aspects:
1. Application startup and initialization
2. Inter-application interaction (launching other applications/being launched by other applications)
3. Multiple instance management
4. Application exit
Application Startup and Initialization
In Qt for HarmonyOS, the application startup process is automatically managed by the system, and developers do not need to concern themselves with the underlying details. The actual process is as follows:
1. The system starts the UIAbility component under the HarmonyOS Stage model
2. The UIAbility component calls to start the Qt thread through NAPI
3. The system automatically loads the shared library of the Qt application and calls the main function of the Qt application
4. The main window of the Qt application is created and displayed in the HarmonyOS WindowStage
For developers, the entry point of the application remains the main function, with no need to focus on additional details.
Inter-application Interaction (Launching Other Applications/Being Launched by Other Applications)
In Qt for HarmonyOS, you can use the API (startAbility) provided by the QtOhosExtras module to launch other applications, replacing the traditional QProcess solution in Qt.
Note: The following methods can only launch applications with a user interface.
Launching Other Applications
Explicit Matching (Specifying Bundle Name and Ability Name)
#include <QtOhosExtras/qohoswant.h>
#include <QtOhosExtras/qohosuiabilitycontext.h>
void MainWindow::startSpecificApp()
{
QtOhosExtras::QOhosWant want;
want.bundleName = "com.example.targetapp"; // Target application bundle name
want.abilityName = "MainAbility"; // Target application Ability name
// Optional: Pass parameters
QJsonObject parameters;
parameters.insert("key", "value");
want.parameters = parameters;
// Launch the target application
QtOhosExtras::startAbility(want);
}
Implicit Matching (Matching through Action and URI)
void MainWindow::startAppByAction()
{
QtOhosExtras::QOhosWant want;
want.action = "ohos.want.action.viewData"; // Action type
want.type = "text/plain"; // Data type
want.uri = "content://example/data"; // Data URI
// Optional: Pass parameters
QJsonObject parameters;
parameters.insert("key", "value");
want.parameters = parameters;
// Launch the matching application
QtOhosExtras::startAbility(want);
}
Being Launched by Other Applications
When a Qt application is launched by other applications, it needs to handle the received Want parameters.
Configure the following in the module's module.json5:
"abilities": [
{
"name": "QAbility",
"srcEntry": "./ets/qability/QAbility.ets",
"launchType": "specified",
"description": "$string:QAbility_desc",
"icon": "$media:icon",
"label": "$string:QAbility_label",
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home",
"ohos.want.action.viewData" // Supported action types
],
"uris": [{"type": "*/*"}] // Supported data types
}
]
}
]
Handling Received Want
#include <QtOhosExtras/QtOhosExtras>
void MainWindow::init()
{
// Connect Want reception signal
QObject::connect(
QtOhosExtras::QOhosUiAbilityContext::instance(),
&QtOhosExtras::QOhosUiAbilityContext::newWantReceived,
this,
&MainWindow::onNewWantReceived
);
}
void MainWindow::onNewWantReceived(QtOhosExtras::QOhosWant want)
{
// Handle received Want parameters
qDebug() << "Received want with action:" << want.action;
qDebug() << "URI:" << want.uri;
qDebug() << "Type:" << want.type;
// Process parameters
if (want.parameters.contains("key")) {
QString value = want.parameters.value("key").toString();
processParameter(value);
}
// Execute corresponding operations based on Want content
if (want.action == "ohos.want.action.viewData") {
openDataForViewing(want.uri);
}
}
Multiple Instance Management
In the HarmonyOS system, applications can have multiple instance modes: singleton, multi-instance single-process, and multi-instance multi-process. Qt for HarmonyOS applications need to choose the appropriate mode based on requirements.
Note: Instances here refer to UIAbility instances.
Singleton Mode
When the application is launched again, it uses the existing instance to handle new requests:
void MainWindow::onNewWantReceived(QtOhosExtras::QOhosWant want)
{
// Use existing window to handle new requests
processNewRequest(want);
this->setText(want.uri); // Singleton single-process: original window handles
}
Multi-instance Single-process Mode
Creates a new UIAbility instance each time it is launched, but shares the same process:
void MainWindow::onNewWantReceived(QtOhosExtras::QOhosWant want)
{
// Create new window instance
MainWindow *newWindow = new MainWindow();
newWindow->processRequest(want);
newWindow->show();
}
Multi-instance Multi-process Mode
Starts a new application process to create a new UIAbility instance to handle requests:
void MainWindow::onNewWantReceived(QtOhosExtras::QOhosWant want)
{
// Start new process
static int processCounter = 0;
QString processName = "Process" + QString::number(processCounter++);
// Use QtOhosExtras to start new process
QtOhosExtras::startAppProcess(processName, want);
}
Note: Multi-instance multi-process mode requires adding configuration in module.json5:
"abilities": [
{
"name": "QAbility",
// Other configurations...
"isolationProcess": true
}
]
Application Exit
Window Close Interception
The HarmonyOS platform provides a multi-level close interception mechanism. Qt for HarmonyOS implements a complete window close event interception system, supporting applications to customize handling in different close scenarios. This guide will detail the implementation mechanism, usage methods, and provide complete code examples.
Qt for HarmonyOS implements complete window close event interception, adapting to HarmonyOS's three-tier pre-close system:
Close Interception Level Architecture
HarmonyOS provides three levels of interception mechanisms, Qt for HarmonyOS currently supports the first two levels:
1. Level 1: Window-Level Interception
- Triggered when user clicks the window close button
- Supports full user interaction, can display save dialog
- User can choose to cancel closing
2. Level 2: Ability-Level Interception
- Triggered when closing from Task Center/Dock thumbnail
- Supports quick save operations
- Time is limited, quick processing recommended
3. Level 3: AbilityStage-Level Interception
- Not currently supported
- Theoretically for highest-priority system-level closing
- Actual scenarios fall back to Level 2 processing
Close Method and Interception Level Correspondence
| Close Method | Interception Level | Application Interception Behavior | System API |
|---|---|---|---|
| Main Window Close Button | Level 1 | Full Interaction: Close/Hide/Minimize | window.onWindowWillClose |
| Sub Window Close Button | Level 1 | Full Interaction: Close/Hide | window.onWindowWillClose |
| Task Center/Dock Thumbnail | Level 2 | Quick Save: Close/Hide/Minimize | ability.onPrepareToTerminate |
| Dock Right-Click Menu | Level 3 | 1. Direct exit or 2. Auto-save and exit |
abilityStage.onPrepareToTerminate not supported Falls back to ability.onPrepareToTerminate |
| System Tray Close | Level 3 | 1. Direct exit or 2. Auto-save and exit |
abilityStage.onPrepareToTerminate not supported Falls back to ability.onPrepareToTerminate |
| System Shutdown | Level 3 | 1. Direct exit or 2. Auto-save and exit |
abilityStage.onPrepareToTerminate not supported Falls back to ability.onPrepareToTerminate |
| Task Manager Force Kill | - | Interception not supported | - |
Qt API Details
Close Event Context System
Qt for HarmonyOS distinguishes different close sources through the close event context system:
- QOhosCloseEventContext - Close Event Context Manager
- QCloseEvent Extension - Added context member on HarmonyOS platform
- QtOhosExtras Public API - Interface provided to developers
Close Reason Enumeration
// QtOhosExtras Public API Enumeration
namespace QtOhosExtras {
enum class CloseEventRootCause {
InternalClose, // Internal close (application programmatically calls close())
AbilityClose, // Ability close (Task Center/Dock thumbnail)
WindowStageClose, // Window close (window close button)
};
}
API for Getting Close Event Root Cause
// API to get the root cause of close event
QtOhosExtras::CloseEventRootCause QtOhosExtras::getCloseEventRootCause(QCloseEvent *event);
Parameter Details
| Parameter | Type | Description |
|---|---|---|
| event | QCloseEvent* | Qt close event object pointer |
Return Value Description
| Return Value | Meaning | Trigger Scenario |
|---|---|---|
| InternalClose | Internal Close | Application calls close(), programmatic logic close |
| WindowStageClose | Window-Level Close (Level 1) | User clicks window close button |
| AbilityClose | Ability-Level Close (Level 2) | Task Center, Dock thumbnail close |
Development Implementation
The key to implementing close interception: Override closeEvent() function and handle differently based on close cause
1. Simple Close Interception
#include <QtOhosExtras/QtOhosExtras>
#include <QCloseEvent>
#include <QMessageBox>
class MyMainWindow : public QMainWindow {
protected:
void closeEvent(QCloseEvent *event) override {
// Get the cause of close event
auto rootCause = QtOhosExtras::getCloseEventRootCause(event);
switch (rootCause) {
case QtOhosExtras::CloseEventRootCause::WindowStageClose:
// User clicks close button
handleWindowClose(event);
break;
case QtOhosExtras::CloseEventRootCause::AbilityClose:
// Task Center close
handleAbilityClose(event);
break;
case QtOhosExtras::CloseEventRootCause::InternalClose:
// Program internal close
event->accept();
break;
}
}
private:
void handleWindowClose(QCloseEvent *event) {
// Window close button: can show dialog
if (hasUnsavedData()) {
int ret = QMessageBox::question(this, "Confirm Close",
"There is unsaved data, do you want to save?",
QMessageBox::Save |
QMessageBox::Discard |
QMessageBox::Cancel);
if (ret == QMessageBox::Save) {
saveData();
event->accept();
} else if (ret == QMessageBox::Discard) {
event->accept();
} else {
event->ignore(); // Cancel close
}
} else {
event->accept();
}
}
void handleAbilityClose(QCloseEvent *event) {
// Task Center close: quick processing
if (hasUnsavedData()) {
saveData(); // Auto save
}
event->accept();
}
bool hasUnsavedData() const {
// Check if there is unsaved data
return m_hasUnsavedData;
}
void saveData() {
// Save data
m_hasUnsavedData = false;
}
private:
bool m_hasUnsavedData = false;
};
2. Project Configuration
# Project Configuration File
QT += core gui widgets ohosextras
SOURCES += main.cpp mainwindow.cpp
HEADERS += mainwindow.h
QT += ohosextras: Must add this module to use close interception API
Applicable Scenarios
- Document Editors: Applications like Word, Excel that require save confirmation
- Code Editors: IDEs, code editors and other development tools
- Graphic Design Software: Photoshop-like applications, prevent accidental work loss
- Database Management Tools: Applications requiring data integrity
- Media Editing Applications: Video/audio editors and other long-duration work applications
Development Notes
Level 3 Interception Support Status
- Current Status: Level 3 interception (abilityStage.onPrepareToTerminate) not currently supported
- Affected Scenarios: System shutdown, Dock right-click menu, system tray close, etc.
- Actual Behavior: These scenarios may trigger Level 2 interception (ability.onPrepareToTerminate), manifested as AbilityClose events
Usage Recommendations
- Window close: Can display complete save dialog
- Task Center close: Recommend quick auto-save, avoid time-consuming operations
- System-level close: System shutdown, Dock right-click menu and other scenarios may trigger AbilityClose events, should handle properly
- Testing and Verification: Test under different close methods to ensure application responds correctly
```