开天辟地 HarmonyOS(鸿蒙) - 开发基础: AppStartup - 启动任务

源码 https://github.com/webabcd/HarmonyDemo
作者 webabcd

开天辟地 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)}`)
  }
}

源码 https://github.com/webabcd/HarmonyDemo
作者 webabcd

posted @ 2025-04-15 09:42  webabcd  阅读(126)  评论(0)    收藏  举报