概述
在应用开发过程中,组件的生命周期尤为重要,当用户打开、切换和返回到对应应用时,应用中的UIAbility实例会在其生命周期的不同状态之间转换。我们可以通过生命周期来对应用的状态进行监控并执行特定的操作。比如在创建时进行应用初始化、销毁时进行数据清除等。本文主要简单介绍了Stage模型中UIAbility的生命周期,希望能帮助到大家。详细请跳转至官网了解【UIAbility生命周期】
Stage模型基本概念
在介绍UIAbility生命周期之前,首先先了解一下Stage应用模型的一些基本概念。先看下图,描述了Stage模型的概念图。
上图可以看出,当我们的应用经过编译打包之后生成的HAP包,在安装之后运行时会先创建一个AbilityStage实例(可以将AbilityStage实例理解为整个Stage应用实例)。然后Stage模型提供了两种组件UIAbility组件、ExtensionAbility组件,这两种组件都有具体的类承载,支持面向对象的开发方式。然后UIAbility组件会和WindowStage绑定(WindowStage是应用进程内的窗口管理器),UIAbility会通过WindowStage创建一个窗口(Window)用于页面ArkUI Page的渲染。而ArkUI Page中就是我们写的page页面。其中生成AbilityStage实例的时候也会生成全局基本的Context上下文,然后UIAbility组件和各种ExtensionAbility派生类都有各自不同的Context类(UIAbilityContext),他们都继承自基类Context,但是各自又根据所属组件,提供不同的能力。
名称解释
可能看到上面,有点头昏,不清楚什么是HAP、Conetext、WindowStage…这些名词,所以在这里简单介绍一下这个名词的定义。
-
Module
Module是HarmonyOS应用的基本功能单元,一个Module包含源代码、资源文件、第三方依赖、服务配置等文件,每一个Module都可以单独进行编译打包运行。一个应用可以有多个Module,而一个Module包含Ability(UIAbility)和Library两类。
可以理解为一个Module就是一个独立的小应用,而一个大应用可以有多个小应用(Module)集成。一个Module(小应用)包含多个UIAbility。
应用程序App、Module、Ability、Library的关系如下:
-
HAR和HSP
Ability类型的Module经过编译打包后生成的.hap文件就是HAP(Harmony Ability Package应用程序包),Library类型的Module打包之后就是HAR(Harmony Archive)或者叫HSP(Harmony Shared Package 共享包)。由命名就能看出Library类型的包可以支持其他HAP应用程序当作第三方引入。 -
AbilityStage
每个Entry类型或者Feature类型的HAP在运行期都有一个AbilityStage类实例,当HAP中的代码首次被加载到进程中的时候,系统会先创建AbilityStage实例。 -
UIAbility组件和ExtensionAbility组件
Stage模型提供UIAbility和ExtensionAbility两种类型的组件,这两种组件都有具体的类承载,支持面向对象的开发方式。-
UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。例如,图库类应用可以在UIAbility组件中展示图片瀑布流,在用户选择某个图片后,在新的页面中展示图片的详细内容。同时用户可以通过返回键返回到瀑布流页面。UIAbility的生命周期只包含创建/销毁/前台/后台等状态,与显示相关的状态通过WindowStage的事件暴露给开发者。每一个UIAbility组件实例,都对应于一个最近任务列表中的任务。
-
ExtensionAbility组件是一种面向特定场景的应用组件。开发者并不直接从ExtensionAbility派生,而是需要使用ExtensionAbility的派生类。目前ExtensionAbility有用于卡片场景的FormExtensionAbility,用于闲时任务场景的WorkSchedulerExtensionAbility等多种派生类,这些派生类都是基于特定场景提供的。例如,用户在桌面创建应用的卡片,需要应用开发者从FormExtensionAbility派生,实现其中的回调函数,并在配置文件中配置该能力。ExtensionAbility派生类实例由用户触发创建,并由系统管理生命周期。在Stage模型上,普通应用开发者不能开发自定义服务,而需要根据自身的业务场景通过ExtensionAbility的派生类来实现。
-
-
WindowStage
每个UIAbility类实例都会与一个WindowStage类实例绑定,WindowStage类起到了应用进程内窗口管理器的作用,它包含一个主窗口。也就是说,UIAbility通过WindowStage持有了一个窗口,该窗口为ArkUI提供了绘制区域。 -
Context
在Stage模型上,Context及其派生类向开发者提供在运行期可以调用的各种能力。UIAbility组件和各种ExtensionAbility派生类都有各自不同的Context类,他们都继承自基类Context,但是各自又根据所属组件,提供不同的能力。
Stage基本概念总结
可能上面太多定义性的东西,不太好理解,所以这里说一下我的理解,如果有问题欢迎评论指正。
在基于Stage模型进行应用开发后,经过编译打包生成.hap文件,在用户终端上安装之后,点击运行时会先创建一个Stage实例和基本上下文Context。然后该Stage实例上提供两个组件UIAbility组件和ExtensionAbility组件。然后UIAbility通过WindowStage(窗口管理器)来创建了一个window窗口来进行ArkUI Page的显示。在这个过程中不同的UIAbility组件和ExtensionAbility派生类都会基于基本Context来封装各自不同的Context类(UIAbilityContext),并提供各种独特的功能。
UIAbility生命周期
进入正题,在实际用户使用应用的过程中无非就是打开、切换、返回、关闭应用,所以UIAbility的生命周期只有4个。分别为创建Create、前台Foreground、后台Background、销毁Destory。
这里主要介绍上述的这几个API,更加详细的可以查看官网【@ohos.app.ability.UIAbility (UIAbility)】
生命周期图如下:
PS: 生命周期都是在EntryAbility.ts文件中写的
Create
应用加载过程中,UIAbility创建实例之前会触发onCreate回调,在该回调我们可以进行数据的初始化操作,比如全局变量定义、资源加载请求等。接收两个参数(want,launchParam),其中want表示当前UIAbility的信息,包括ability名称、bundle名称等。launchParam表示创建UIAbility时上一次异常的信息(如果有的话)。
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// 页面初始化
}
// ...
}
Foreground
在UIAbility实例切换至前台,UIAbility界面还没有显示之前会触发onForeground回调,比如开启应用/由后台切回的时候,在该回调中我们可以用于系统资源的请求或者请求处于后台时被释放的资源。
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onForeground() {
// 申请系统需要的资源,或者重新申请在onBackground中释放的资源
}
}
Background
在UIAbility实例切换至后台,UIAbility界面完全消失之后会触发onBackground回调,比如应用切换到后台的时候,在该回调中我们可以进行耗时操作、资源的释放或者数据的保存。
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onBackground() {
// 释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作
// 例如状态保存等
}
}
EG:当应用需要开启定位的时候,由于实时定位很耗时和资源,所以当使用应用(处于前台时,开启定位),当将应用切换到后台的时候就关闭定位,然后等待用户切换到前台时,再重新开启定位,以减少资源消耗。
Destory
当关闭应用时候会触发onDestory回调,一般在这个回调进行资源释放、数据的持久化保存(PersistentStorage)等操作。
PersistentStorage持久化,简而言之就是通过状态管理AppStorage来写入数据,然后会选择需要持久化保存的状态,会从AppStorage自动同步到PersistentStorage。 PersistentStorage之所以能保存,是因为它会在用户本地磁盘创建一个文件来保存数据。具体的可以查看这篇文章【HarmonyOS - ArkTS - 状态管理】
例如调用terminateSelf()方法停止当前UIAbility实例,从而完成UIAbility实例的销毁;或者用户使用最近任务列表关闭该UIAbility实例,完成UIAbility的销毁。
terminateSelf就是harmonyOS内置的停止当前Ability实例的一个接口。
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onDestroy() {
// 系统资源的释放、数据的保存等
}
}
额外的WindowStage生命周期
在第一部分Stage的基本概念图中,我们能看到打开一个应用时UiAbility会绑定WindowStage来创建一个窗口,而在这个创建窗口的阶段,Stage也提供了两个生命周期WindowStageCreate、WindowStageDestroy来表示窗口创建和销毁的状态。
WindowStageCreate
UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。WindowStage创建完成后会进入onWindowStageCreate()回调,可以在该回调中设置UI界面加载、设置WindowStage的事件订阅。
一般会在onWindowStageCreate()回调中通过loadContent()方法设置应用要加载的页面并根据需要订阅WindowStage的事件(获焦/失焦、可见/不可见)。
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: Window.WindowStage) {
// 设置WindowStage的事件订阅(获焦/失焦、可见/不可见)
// 设置UI界面加载
windowStage.loadContent('pages/Index', (err, data) => {
// ...
});
}
}
WindowStageDestroy
对应于onWindowStageCreate()回调。在UIAbility实例销毁之前,则会先进入onWindowStageDestroy()回调,可以在该回调中释放UI界面资源。例如在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件。
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
// ...
onWindowStageDestroy() {
// 释放UI界面资源
}
}
onNewWant
类似onCreate生命周期,也有两个参数want,auchParams。其中want表示 Want类型参数,如ability名称,包名等。launchParams表示UIAbility启动的原因、上次异常退出的原因信息。 当我们从一个UIAbilityA调整另一个UiAbilityB的时候,如果跳转之前UIAbilityB已经创建好了,则不会触发onCreate()和onWindowStageCreate()生命周期回调,需要在onNewWant()回调中解析调用方传递过来的want参数,并挂载到全局变量globalThis中,以便于后续在页面中获取
class MyUIAbility extends Ability {
onNewWant(want, launchParams) {
console.log('onNewWant, want:' + want.abilityName);
console.log('onNewWant, launchParams:' + JSON.stringify(launchParams));
}
}
当被调用方Ability的启动模式设置为multiton启动模式时,每次启动都会创建一个新的实例,那么onNewWant()回调就不会被用到,还是走的正常onCreate、onWindowStageCreate周期。
WindowStageCreate和Create、WindowStageDestroy和Destory的区别?
看了上面的介绍,可能有人产生了正如标题的疑问,想知道两者的区别。事实上当UIAbility实例创建完成之后会立马调用onCreate回调,然后会创建WindowStage进而调用WindowStageCreate回调。同理,在UIAbility组件销毁之前会优先调用WindowStage的WindowStageDestroy回调,然后销毁完成之后会调用Destroy回调。
所以我们的执行顺序是这样的:onCreate -> windowStageCreate -> windowStageDestroy -> Destroy. 详细流程可查看下图
题外话 - 小广告
有兴趣的同学可以关注一下小弟的公众号,以便能实时交流和学习以及即使反馈问题:【大前端小册子】