文档管理中心

应用预加载

概述

从API version 20开始,提供应用预加载机制。该机制会根据用户的使用习惯,在系统资源充足时提前加载应用至特定阶段。当用户启动应用时,由于此前已完成了应用的部分加载,所需的启动时间会缩短,有助于提升用户体验和应用竞争力。

该机制尤其适用于因加载大量资源而启动耗时较长的应用,例如大型游戏应用和大型办公应用。

约束限制

  • 仅支持entry模块的AbilityStage和UIAbility预加载。无论预加载到哪种阶段,entry模块必须配置入口UIAbility,详见开发步骤中步骤2。

  • 应用配置预加载后,实际是否进行预加载以及具体的预加载时机,均由系统根据用户习惯等信息来综合决定。开发者无法对此进行干预。

运行机制

当系统资源充足时,系统将应用加载到特定阶段,提升启动速度。当前支持预加载到三种阶段。开发者可以根据应用冷启动各阶段耗时情况,选择其中的一种。

说明

在应用预加载过程中不会显示任何界面,因此在预加载的任何阶段不应包含与界面显示、界面交互或依赖用户可见的相关操作,同时应确保用户正式启动应用后,所有功能正常运行且体验不受影响。

  • processCreated:进程创建完成阶段。开发者配置此阶段后,预加载机制会创建空进程并初始化Application,但是不会触发任何生命周期回调。

  • abilityStageCreated:AbilityStage创建完成阶段。开发者配置此阶段后,预加载机制会创建空进程并初始化Application,随后触发entry模块AbilityStageonCreate回调。

  • windowStageCreated:WindowStage创建完成阶段。开发者配置此阶段后,预加载机制会创建空进程并初始化Application,随后触发entry模块AbilityStageonCreate回调。接着会拉起entry模块的入口UIAbility,并触发其onCreate回调和onWindowStageCreate回调。开发者可以在UIAbility的onCreate回调中,通过launchParam.launchReason的枚举值获取启动原因。枚举值为PRELOAD表示当前UIAbility是由预加载机制启动的。

应用预加载状态识别与判断

从API version 22开始,应用可以在启动过程中识别并判断当前进程的预加载状态。

当应用被预加载后,开发者可以在AbilityStageonCreate生命周期回调中,通过调用application.getAppPreloadType()获取当前进程的预加载类型(返回值为AppPreloadType)。从而判断本次启动是否由预加载触发,并明确应用当前正处于哪一个预加载阶段。

说明
收起
自动换行
深色代码主题
复制
  1. import { AbilityStage, application } from '@kit.AbilityKit';
  2. export default class MyAbilityStage extends AbilityStage {
  3. onCreate() {
  4. // 根据appPreloadType的值判断当前进程的预加载类型
  5. let appPreloadType = application.getAppPreloadType();
  6. }
  7. }

除了在AbilityStage中判断进程级别的预加载类型外,若应用配置的预加载阶段为windowStageCreated,开发者还可以在UIAbility的onCreate生命周期回调中进行判断。通过校验launchParam.launchReason是否等于PRELOAD,即可识别当前UIAbility实例是否由预加载机制启动。具体实现请参考开发步骤中的步骤3。

应用声明支持预加载到abilityStageCreated阶段

从HarmonyOS 6.0.0开始,在Phone、Tablet和PC/2in1设备上,应用应尽量声明支持预加载到abilityStageCreated阶段。

应用需确保在预加载启动阶段(AbilityStage.onCreate)以及后续用户点击后的完整启动阶段(UIAbility.onCreate、UIAbility.onForeground)中,业务初始化逻辑均能正确执行。

不同设备类型预加载到windowStage阶段的生命周期差异

从HarmonyOS 6.0.0开始,PC/2in1设备上的应用支持预加载到windowStage阶段;从HarmonyOS 7.0.0开始,该能力进一步扩展至Phone和Tablet设备。

不同设备类型的应用在执行预加载启动时,生命周期触发状态存在差异,具体如下表所示。

表1 不同设备类型预加载到windowStage阶段的生命周期差异说明

展开
应用选项 预加载生命周期
"deviceTypes": ["phone","tablet","2in1"] 加载至后台
"deviceTypes": ["phone","tablet"] 加载至后台
"deviceTypes": ["phone","2in1"] 加载至后台
"deviceTypes": ["phone"] 加载至后台
"deviceTypes": ["tablet"] 加载至后台
"deviceTypes": ["tablet","2in1"] 加载至前台初始
"deviceTypes": ["2in1"] 加载至前台初始
  • 支持Phone或仅支持Tablet的应用:加载至后台

    执行预加载启动时,系统会启动一个UIAbility至后台状态,依次触发UIAbility.onCreate()、UIAbility.onWindowStageCreate()、UIAbility.onBackground()生命周期回调(不会触发onForeground()),一小段时间后应用进程会被挂起。

    用户点击应用启动到前台时,系统会依次触发UIAbility.onNewWant()、UIAbility.onForeground()生命周期回调,走完前台启动流程。

  • 支持PC/2in1且不支持Phone的应用:加载至隐藏窗口前台初始状态

    此类应用在UIAbility生命周期中无后台状态,详见不同设备UIAbility生命周期的差异化行为

    执行预加载启动时,系统会启动一个UIAbility至隐藏窗口前台初始状态,依次触发UIAbility.onCreate()、UIAbility.onWindowStageCreate()生命周期回调,并初始化一个隐藏窗口,一小段时间后应用进程会被挂起。

    用户点击应用启动到前台时,系统会依次触发UIAbility.onNewWant()、UIAbility.onForeground()生命周期回调,走完前台启动流程。

开发步骤

  1. 声明应用支持预加载到的阶段。

    以windowStageCreated阶段为例,在app.json5配置文件中配置appPreloadPhase标签。

    收起
    自动换行
    深色代码主题
    复制
    1. {
    2. "app": {
    3. "bundleName": "com.demo.preloadtest",
    4. "vendor": "example",
    5. "versionCode": 1000000,
    6. "versionName": "1.0.0",
    7. "icon": "$media:layered_image",
    8. "label": "$string:app_name",
    9. "appPreloadPhase": "windowStageCreated"
    10. }
    11. }
  2. 配置入口UIAbility(新建工程默认已自动配置)。

    1. 以EntryAbility为例,在entry模块的module.json5配置文件中,设置mainElement为EntryAbility,且EntryAbility的skills标签下面的entities中添加"entity.system.home"、actions中添加"ohos.want.action.home"。

    2. app.json5配置文件中的appPreloadPhase配置为windowStageCreated时,需要在entry模块的module.json5配置文件中配置EntryAbility的launchType标签为singletonspecified

    收起
    自动换行
    深色代码主题
    复制
    1. {
    2. "module": {
    3. "name": "entry",
    4. "type": "entry",
    5. "mainElement": "EntryAbility",
    6. // ...
    7. "abilities": [
    8. {
    9. "name": "EntryAbility",
    10. "srcEntry": "./ets/entryability/EntryAbility.ets",
    11. "launchType": "singleton",
    12. "skills": [
    13. {
    14. "entities": [
    15. "entity.system.home"
    16. ],
    17. "actions": [
    18. "ohos.want.action.home"
    19. ]
    20. }
    21. ]
    22. // ...
    23. }
    24. ]
    25. }
    26. }
  3. (可选)获取UIAbility启动原因。

    仅当appPreloadPhase配置为windowStageCreated时,开发者可在UIAbility的onCreate生命周期回调中通过launchParam.launchReason的枚举值获取启动原因。枚举值为PRELOAD表示当前UIAbility是由预加载机制启动的。

    收起
    自动换行
    深色代码主题
    复制
    1. import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
    2. export default class EntryAbility extends UIAbility {
    3. onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    4. console.info(`EntryAbility onCreate, LaunchReason:${launchParam.launchReason}`);
    5. // 判断是否是预加载启动
    6. let isPreloadStart = launchParam.launchReason === AbilityConstant.LaunchReason.PRELOAD;
    7. // ...
    8. }
    9. }
  4. 使用调试命令主动触发应用预加载。

    收起
    自动换行
    深色代码主题
    复制
    1. $ hidumper -s 1901 -a 'preloadAbilityStage com.ohos.preloadapplication.testapp'
    2. -------------------------------[ability]-------------------------------
    3. ----------------------------------ResourceSched----------------------------------
    4. $ hidumper -s 1901 -a 'preloadWindowStage com.ohos.preloadapplication.testapp TestAppMainUIAbility'
    5. -------------------------------[ability]-------------------------------
    6. ----------------------------------ResourceSched----------------------------------

常见问题

启动时延计算错误

问题现象

应用在AbilityStage.onCreate中记录启动起始时间戳,在应用绘制或onForeground时记录启动截止时间戳,以两者差值计算启动时延。由于预加载启动阶段与用户点击启动阶段可能间隔较久,会导致计算出的启动时延异常偏大。

解决措施

参考预加载状态识别与判断,若本次启动为预加载启动,则不在AbilityStage.onCreate中记录起始时间,应在UIAbility.onCreate中根据launchReason判断后再确定起始时间。

服务器路由地址选路错误

问题现象

应用在AbilityStage.onCreate中执行了连接服务器网络初始化,随后被系统冻结断网,导致应用误判为服务器网络不可用,选择了备用服务器路由地址。

解决措施

参考预加载状态识别与判断,若本次启动为预加载启动,则不执行服务器网络初始化;或重新启动到前台后,优先尝试优选服务器路由地址。

应用内部模块初始化异常

问题现象

应用内部模块初始化分散在AbilityStage.onCreate、UIAbility.onCreate、UIAbility.onForeground中,由于业务执行时间跨度太长,导致业务逻辑执行失败,未完成模块初始化,进而引发部分业务(如Push、VoIP呼叫等)逻辑执行异常。

解决措施

将业务模块初始化操作统一移动到UIAbility.onForeground中。

搜索
请输入您想要搜索的关键词