开天辟地 HarmonyOS(鸿蒙) - 开发基础: AppStartup - 启动任务
开天辟地 HarmonyOS(鸿蒙) - 开发基础: AppStartup - 启动任务
示例如下:
pages\basic\AppStartupDemo.ets
/*
* AppStartup - 启动任务
*
* 主要用于 app 启动时,执行一些自定义任务
* 启动任务可以包含多个自定义任务,且支持设置自定义任务的依赖关系
* 多个自定义任务会并行执行,如果需要串行执行,则可以通过设置自定义任务的依赖关系实现
* 在启动屏,可以等待启动任务执行完成后再继续,也可以不等待
* 启动任务可以在 app 启动时自动执行,也可以之后通过手动执行
*
* 1、在 module.json5 中指定启动任务的配置文件
* {
* "module": {
* "appStartup": "$profile:startup_config", // 启动任务的配置文件
* }
* }
*
* 2、启动任务的配置文件 resources/base/profile/startup_config.json 说明如下
* {
* "configEntry": "./ets/startup/MyStartupConfigEntry.ets", // 启动任务的配置的代码地址(用于设置启动任务的超时时间,并可以监听启动任务的执行情况)
* "startupTasks": [ // 启动任务包含的自定义任务列表
* {
* "name": "StartupTask1", // 任务名称
* "srcEntry": "./ets/startup/StartupTask1.ets", // 任务的代码地址
* "dependencies": [ // 此任务的依赖任务的名称列表(依赖任务完成后,才会执行此任务)
* "StartupTask2",
* "StartupTask3"
* ],
* "runOnThread": "mainThread", // 此任务执行在 mainThread 或 taskPool
* "waitOnMainThread": false // 当任务执行在 mainThread 时,此字段用于指定是否需要在主线程等待此任务执行完成
* },
* ...
* {
* "name": "StartupTask4",
* "srcEntry": "./ets/startup/StartupTask4.ets",
* "runOnThread": "mainThread",
* "waitOnMainThread": false,
* "excludeFromAutoStart": true // false 代表此任务在 app 启动时自动执行(默认值),true 代表此任务需要通过手动执行
* }
* ]
* }
*/
import { TitleBar } from '../TitleBar';
import { startupManager } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct AppStartupDemo {
@State message: string = "启动任务,具体实现请参见:\n" +
"src/main/resources/base/profile/startup_config.json\n" +
"src/main/ets/startup/MyStartupConfigEntry.ets\n" +
"src/main/ets/startup/StartupTask1.ets\n" +
"src/main/ets/startup/StartupTask2.ets\n" +
"src/main/ets/startup/StartupTask3.ets\n" +
"src/main/ets/startup/StartupTask4.ets"
build() {
Column({space:10}) {
TitleBar()
Text(this.message)
/*
* startupManager.run() - 手动执行启动任务中的指定名称的自定义任务
* startupManager.isStartupTaskInitialized() - 判断指定名称的自定义任务是否执行完成
*/
Button('手动启动 StartupTask4').onClick(() => {
let startupTasks = ["StartupTask4"];
startupManager.run(startupTasks).then(() => {
this.message = `任务 StartupTask4 开始执行`
}).catch((error: BusinessError) => {
this.message = `任务 StartupTask4 执行失败 errCode:${error.code}, errMessage:${error.message}`
})
})
Button('判断 StartupTask4 是否执行完成').onClick(() => {
let startupTask = "StartupTask4";
let initialized = startupManager.isStartupTaskInitialized(startupTask)
this.message = `任务 StartupTask4 的执行结果: ${initialized}`
})
}
}
}
\entry\src\main\resources\base\profile\startup_config.json
{
"configEntry": "./ets/startup/MyStartupConfigEntry.ets",
"startupTasks": [
{
"name": "StartupTask1",
"srcEntry": "./ets/startup/StartupTask1.ets",
"dependencies": [
"StartupTask2",
"StartupTask3"
],
"runOnThread": "mainThread",
"waitOnMainThread": false
},
{
"name": "StartupTask2",
"srcEntry": "./ets/startup/StartupTask2.ets",
"dependencies": [ ],
"runOnThread": "mainThread",
"waitOnMainThread": false
},
{
"name": "StartupTask3",
"srcEntry": "./ets/startup/StartupTask3.ets",
"dependencies": [ ],
"runOnThread": "mainThread",
"waitOnMainThread": false
},
{
"name": "StartupTask4",
"srcEntry": "./ets/startup/StartupTask4.ets",
"dependencies": [ ],
"runOnThread": "mainThread",
"waitOnMainThread": false,
"excludeFromAutoStart": true
}
]
}
\entry\src\main\ets\startup\MyStartupConfigEntry.ets
/*
* StartupConfigEntry - 启动任务的配置
* 用于设置启动任务的超时时间,并可以监听启动任务的执行情况
*/
import { StartupConfig, StartupConfigEntry, StartupListener } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { MyLog } from '../utils/MyLog';
export default class MyStartupConfigEntry extends StartupConfigEntry {
onConfig() {
let onCompletedCallback = (error: BusinessError<void>) => {
if (error) {
// 启动任务超时或异常
MyLog.d(`StartupConfigEntry onCompletedCallback errCode:${error.code}, errMessage:${error.message}`)
} else {
// 启动任务执行完成
MyLog.d(`StartupConfigEntry onCompletedCallback 成功`)
}
};
let startupListener: StartupListener = {
'onCompleted': onCompletedCallback, // 启动任务有结果后(超时或异常或完成)的回调
};
let config: StartupConfig = {
'timeoutMs': 10_000, // 启动任务的超时时间(单位:毫秒)
'startupListener': startupListener // 启动任务的监听器
};
return config;
}
}
\entry\src\main\ets\startup\StartupTask1.ets
/*
* StartupTask - 启动任务中的一个自定义任务
*/
import { StartupTask, common } from '@kit.AbilityKit';
import { MyLog } from '../pages/TitleBar';
// 因为 StartupTask 采用了 Sendable 协议,所以这里必须要通过 @Sendable 装饰
@Sendable
export default class StartupTask1 extends StartupTask {
constructor() {
super();
}
// 自定义任务开始执行,在此处写任务的具体逻辑
async init(context: common.AbilityStageContext) {
MyLog.d(`StartupTask1 init`)
// 睡 2 秒
// 我这里测试发现,当这里执行异步任务时
// 如果当前任务执行在 mainThread(在 startup_config.json 中配置的),则一切正常
// 如果当前任务执行在 taskPool(在 startup_config.json 中配置的),则无法获知当前任务执行完成,最后会在 StartupConfigEntry 中得到启动任务超时的回调
await new Promise<void>((r) => { setTimeout(r, 2000) })
// 返回执行结果,可以是任意对象,或者不返回
return 'StartupTask1_Completed';
}
// 当前任务的某一个依赖任务执行完成后的回调
onDependencyCompleted(dependence: string, result: Object): void {
// dependence - 执行完的依赖任务的名称
// result - 执行完的依赖任务的返回结果(即依赖任务在 init 中 return 的结果)
MyLog.d(`StartupTask1 onDependencyCompleted dependence:${dependence}, result:${JSON.stringify(result)}`)
}
}
\entry\src\main\ets\startup\StartupTask2.ets
import { StartupTask, common } from '@kit.AbilityKit';
import { MyLog } from '../pages/TitleBar';
@Sendable
export default class StartupTask2 extends StartupTask {
constructor() {
super();
}
async init(context: common.AbilityStageContext) {
MyLog.d(`StartupTask2 init`)
await new Promise<void>((r) => { setTimeout(r, 2000) })
return 'StartupTask2_Completed';
}
onDependencyCompleted(dependence: string, result: Object): void {
MyLog.d(`StartupTask2 onDependencyCompleted dependence:${dependence}, result:${JSON.stringify(result)}`)
}
}
\entry\src\main\ets\startup\StartupTask3.ets
import { StartupTask, common } from '@kit.AbilityKit';
import { MyLog } from '../pages/TitleBar';
@Sendable
export default class StartupTask3 extends StartupTask {
constructor() {
super();
}
async init(context: common.AbilityStageContext) {
MyLog.d(`StartupTask3 init`)
await new Promise<void>((r) => { setTimeout(r, 2000) })
return 'StartupTask3_Completed';
}
onDependencyCompleted(dependence: string, result: Object): void {
MyLog.d(`StartupTask3 onDependencyCompleted dependence:${dependence}, result:${JSON.stringify(result)}`)
}
}
\entry\src\main\ets\startup\StartupTask4.ets
import { StartupTask, common } from '@kit.AbilityKit';
import { MyLog } from '../pages/TitleBar';
@Sendable
export default class StartupTask4 extends StartupTask {
constructor() {
super();
}
async init(context: common.AbilityStageContext) {
MyLog.d(`StartupTask4 init`)
await new Promise<void>((r) => { setTimeout(r, 2000) })
return 'StartupTask4_Completed';
}
onDependencyCompleted(dependence: string, result: Object): void {
MyLog.d(`StartupTask4 onDependencyCompleted dependence:${dependence}, result:${JSON.stringify(result)}`)
}
}