鸿蒙 UIAbility的启动方式:startAbilityForResult
·
本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一. 概述
UIAbility 是 HarmonyOS 系统调度的最小单元,负责应用的功能模块。在应用内部,经常需要从一个 UIAbility 跳转到另一个 UIAbility。
二. 基本启动方式
2.1 简单启动 UIAbility
场景:从当前 UIAbility 启动另一个 UIAbility,不需要返回结果。
核心方法:startAbility()
示例:
import { common, Want } from '@kit.AbilityKit';
import { logger } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
const LOG_TAG: string = '[MainPage]';
const DOMAIN_ID: number = 0xFF00;
@Entry
@Component
struct MainApplicationPage {
// 获取 UIAbility 上下文
private abilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
build() {
Column() {
List({ initialIndex: 0 }) {
ListItem() {
Row() {
Text('启动功能页面')
.fontSize(18)
}
.padding(12)
}
.onClick(() => {
// 构造启动参数
let targetWant: Want = {
deviceId: '', // 空字符串表示本设备
bundleName: 'com.example.myapplication',
moduleName: 'feature', // 可选参数,不同模块时需要
abilityName: 'FeatureAbility',
parameters: {
// 自定义参数
source: '来自主页面',
timestamp: new Date().getTime()
}
};
// 启动目标 UIAbility
this.abilityContext.startAbility(targetWant).then(() => {
logger.info(DOMAIN_ID, LOG_TAG, '功能页面启动成功');
}).catch((error: BusinessError) => {
logger.error(DOMAIN_ID, LOG_TAG,
`启动失败: 错误码 ${error.code}, 错误信息 ${error.message}`);
});
})
}
}
}
}
2.2 目标 UIAbility 接收参数
在被启动的 UIAbility 中接收传递过来的参数:
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
export default class FeatureAbility extends UIAbility {
private receivedSource: string = '';
private receivedTimestamp: number = 0;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 接收调用方传递的参数
this.receivedSource = want?.parameters?.source as string || '未知来源';
this.receivedTimestamp = want?.parameters?.timestamp as number || 0;
console.info(`来自: ${this.receivedSource}, 时间: ${this.receivedTimestamp}`);
}
}
三. 启动并获取返回结果
3.1 带结果启动
场景:启动另一个 UIAbility 并期望在目标 UIAbility 完成操作后返回结果。
核心方法:startAbilityForResult()
示例:
import { common, Want } from '@kit.AbilityKit';
import { logger } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
const LOG_TAG: string = '[MainPage]';
const DOMAIN_ID: number = 0xFF00;
const LOGIN_RESULT_CODE: number = 1001;
@Entry
@Component
struct LoginEntryPage {
private abilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
build() {
Column() {
Button('用户登录')
.onClick(() => {
let loginWant: Want = {
deviceId: '',
bundleName: 'com.example.myapplication',
abilityName: 'UserLoginAbility',
parameters: {
loginType: 'password',
rememberMe: true
}
};
// 启动登录页面并等待结果
this.abilityContext.startAbilityForResult(loginWant).then((resultData) => {
if (resultData?.resultCode === LOGIN_RESULT_CODE) {
// 解析返回的登录结果
const userInfo = resultData.want?.parameters?.userData;
const loginSuccess = resultData.want?.parameters?.success;
if (loginSuccess) {
logger.info(DOMAIN_ID, LOG_TAG, `用户登录成功: ${JSON.stringify(userInfo)}`);
this.getUIContext().getPromptAction().showToast({
message: '登录成功'
});
}
}
}).catch((error: BusinessError) => {
logger.error(DOMAIN_ID, LOG_TAG,
`登录流程失败: 错误码 ${error.code}, 错误信息 ${error.message}`);
});
})
}
}
}
3.2 返回结果给调用方
在被启动的 UIAbility 中返回结果:
import { common } from '@kit.AbilityKit';
import { logger } from '@kit.PerformanceAnalysisKit';
const LOG_TAG: string = '[LoginPage]';
const DOMAIN_ID: number = 0xFF00;
const LOGIN_RESULT_CODE: number = 1001;
@Entry
@Component
struct UserLoginPage {
private abilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
build() {
Column() {
Button('确认登录')
.onClick(() => {
// 构造返回结果
let loginResult: common.AbilityResult = {
resultCode: LOGIN_RESULT_CODE,
want: {
bundleName: 'com.example.myapplication',
abilityName: 'MainAbility',
parameters: {
success: true,
userData: {
userId: '12345',
userName: '张三',
token: 'abc123xyz'
}
}
}
};
// 返回结果并结束当前 UIAbility
this.abilityContext.terminateSelfWithResult(loginResult, (error) => {
if (error?.code) {
logger.error(DOMAIN_ID, LOG_TAG,
`返回结果失败: 错误码 ${error.code}, 错误信息 ${error.message}`);
return;
}
logger.info(DOMAIN_ID, LOG_TAG, '登录结果返回成功');
});
})
}
}
}
4. 启动指定页面
4.1 调用方指定目标页面
场景:启动 UIAbility 时直接跳转到指定的页面。
import { common, Want } from '@kit.AbilityKit';
import { logger } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
const LOG_TAG: string = '[MainPage]';
const DOMAIN_ID: number = 0xFF00;
@Entry
@Component
struct ApplicationMainPage {
private abilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
build() {
Column() {
// 跳转到设置页面
Button('系统设置')
.onClick(() => {
this.navigateToSpecificPage('settings');
})
// 跳转到个人资料页面
Button('个人资料')
.onClick(() => {
this.navigateToSpecificPage('profile');
})
}
}
private navigateToSpecificPage(pageRoute: string): void {
let navigationWant: Want = {
deviceId: '',
bundleName: 'com.example.myapplication',
abilityName: 'FeatureAbility',
parameters: {
targetPage: pageRoute, // 指定目标页面
navigationSource: '主页面'
}
};
this.abilityContext.startAbility(navigationWant).then(() => {
logger.info(DOMAIN_ID, LOG_TAG, `跳转到 ${pageRoute} 页面成功`);
}).catch((error: BusinessError) => {
logger.error(DOMAIN_ID, LOG_TAG,
`页面跳转失败: 错误码 ${error.code}, 错误信息 ${error.message}`);
});
}
}
4.2 目标 UIAbility 冷启动处理
冷启动:UIAbility 实例完全关闭状态下被启动。
import { AbilityConstant, Want, UIAbility } from '@kit.AbilityKit';
import { logger } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
const DOMAIN_ID: number = 0xFF00;
const LOG_TAG: string = '[FeatureAbility]';
export default class FeatureAbility extends UIAbility {
private incomingWant: Want | undefined = undefined;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 保存启动参数
this.incomingWant = want;
logger.info(DOMAIN_ID, LOG_TAG, 'FeatureAbility 创建');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
logger.info(DOMAIN_ID, LOG_TAG, '窗口阶段创建');
// 根据参数决定加载哪个页面
let targetPageUrl = 'pages/Index'; // 默认页面
const requestedPage = this.incomingWant?.parameters?.targetPage;
if (requestedPage === 'settings') {
targetPageUrl = 'pages/SettingsPage';
} else if (requestedPage === 'profile') {
targetPageUrl = 'pages/UserProfilePage';
}
// 加载指定页面
windowStage.loadContent(targetPageUrl, (error, data) => {
if (error?.code) {
logger.error(DOMAIN_ID, LOG_TAG,
`页面加载失败: 错误码 ${error.code}`);
return;
}
logger.info(DOMAIN_ID, LOG_TAG, `页面加载成功: ${targetPageUrl}`);
});
}
}
4.3 目标 UIAbility 热启动处理
热启动:UIAbility 实例已经启动过并切换到后台,再次启动时触发。
import { AbilityConstant, Want, UIAbility } from '@kit.AbilityKit';
import { logger } from '@kit.PerformanceAnalysisKit';
import { window, UIContext } from '@kit.ArkUI';
import { AppStorage } from '@kit.ArkUI';
const DOMAIN_ID: number = 0xFF00;
const LOG_TAG: string = '[MessageAbility]';
export default class MessageAbility extends UIAbility {
private uiContext: UIContext | undefined = undefined;
onWindowStageCreate(windowStage: window.WindowStage): void {
// 获取 UIContext 用于后续热启动时页面跳转
windowStage.getMainWindow((error, windowData) => {
if (error?.code) {
logger.error(DOMAIN_ID, LOG_TAG,
`获取主窗口失败: 错误码 ${error.code}`);
return;
}
this.uiContext = windowData.getUIContext();
});
windowStage.loadContent('pages/MessageIndex', (error, data) => {
// 正常加载首页
});
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
logger.info(DOMAIN_ID, LOG_TAG, '热启动 - onNewWant');
// 处理新的启动意图,设置全局变量用于页面跳转
const contactName = want?.parameters?.contactName;
if (contactName) {
AppStorage.setOrCreate<string>('selectedContact', contactName);
AppStorage.setOrCreate<boolean>('navigateToChat', true);
}
}
}
4.4 热启动页面跳转处理
在首页面中监听全局变量变化并执行跳转:
// MessageIndex.ets
@Entry
@Component
struct MessageIndexPage {
@State currentMessage: string = '消息首页';
messageStack: NavPathStack = new NavPathStack();
onPageShow(): void {
// 检查是否有需要跳转的页面
const shouldNavigate = AppStorage.get<boolean>('navigateToChat');
const targetContact = AppStorage.get<string>('selectedContact');
if (shouldNavigate && targetContact) {
// 跳转到聊天页面
this.messageStack.pushPath({
name: 'chatPage',
param: { contact: targetContact }
}, false);
// 清理全局变量
AppStorage.delete('navigateToChat');
AppStorage.delete('selectedContact');
}
}
build() {
Navigation(this.messageStack) {
Column() {
Text(this.currentMessage)
.fontSize(20)
.fontWeight(FontWeight.Bold)
}
}
.mode(NavigationMode.Stack)
.height('100%')
.width('100%')
}
}
5. UIAbility 的停止和清理
5.1 停止当前 UIAbility
import { common } from '@kit.AbilityKit';
import { logger } from '@kit.PerformanceAnalysisKit';
const LOG_TAG: string = '[CurrentPage]';
const DOMAIN_ID: number = 0xFF00;
@Entry
@Component
struct CurrentFeaturePage {
build() {
Column() {
Button('完成并返回')
.onClick(() => {
this.finishCurrentAbility();
})
Button('取消操作')
.onClick(() => {
this.cancelAndExit();
})
}
}
private finishCurrentAbility(): void {
const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
context.terminateSelf((error) => {
if (error?.code) {
logger.error(DOMAIN_ID, LOG_TAG,
`停止失败: 错误码 ${error.code}, 错误信息 ${error.message}`);
return;
}
logger.info(DOMAIN_ID, LOG_TAG, '页面正常退出');
});
}
private cancelAndExit(): void {
const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
context.terminateSelf();
}
}
5.2 配置不保留快照
在 module.json5 中配置 UIAbility 停止后不保留快照:
{
"module": {
"abilities": [
{
"name": "FeatureAbility",
"removeMissionAfterTerminate": true
}
]
}
}
更多推荐

所有评论(0)