鸿蒙HarmonyOS 4-Stage模型
Stage模型概述
- 详细内容可以看一下鸿蒙开发者文档
- 模块是应用的基本功能单元,包含源代码、资源以及配置文件等内容
- 模块分为两大类,像entry这样的模块称为Ability Module能力模块,而通用的资源等可以放在一个模块当中,这样的模块成为Library Module,Ability Module就可以去引用Library的模块了。
- 整个源码会被编译打包成APP,为了降低不同功能模块之间的耦合,每一个模块都是可以独立编译和运行的,所有的Ability Module会被编译成HAP文件,而Library Module会被编译成HSP文件。
- 一个应用有且只有一个Entry类型的HAP文件,而Feature类型可以有多个。
- 所有HAP文件最后会打包成Bundle文件,最后一起打包成安装包文件。Bundle name是整个应用的唯一标识。
- HAP在运行时会创建一个名为Ability Stage的实例,理解为应用组件的“舞台”。
- 因为Ability和窗口的分割,可以实现对不同设备窗口的单独裁切适配。
应用配置文件
- 鸿蒙应用的配置文件有两类:
- 第一类值针对这个应用的全局配置文件,在
AppScope/app.json5
1
2
3
4
5
6
7
8
9
10
11//app.json5全局配置文件
{
"app": {
"bundleName": "com.example.myapplication", //是应用的唯一标识,不与其他应用重复,使用域名倒置的方式命名
"vendor": "example",
"versionCode": 1000000, //数字型的版本号
"versionName": "1.0.0", //字符型的版本号
"icon": "$media:app_icon", //应用图标
"label": "$string:app_name" //应用描述
}
} - 第二类是在每个模块里,在每个模块的
src/main/module.json5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44//module.json5模块配置文件
{
"module": {
"requestPermissions": [ //系统权限申请
{
"name": "ohos.permission.INTERNET"
}
],
"name": "entry", //模块名称
"type": "entry", //模块类型,entry入口型、feature功能型、shared共享型
"description": "$string:module_desc", //当前模块的描述,读取的是base/element/string.json
"mainElement": "EntryAbility", //入口ability
"deviceTypes": [ //设备类型
"phone",
"tablet"
],
"deliveryWithInstall": true, //跟随APP安装,Entry类型必须安装,feature可选
"installationFree": false,
"pages": "$profile:main_pages", //模块中的所有页面,读取的是base/profile/main_pages.json
"abilities": [ //可以有多个ability,以数组的形式写出
{
"name": "EntryAbility", //ability的名称
"srcEntry": "./ets/entryability/EntryAbility.ts", //ability的源码位置
"description": "$string:EntryAbility_desc", //ability的描述
"icon": "$media:icon", //ability的图标
"label": "$string:EntryAbility_label", //当前ability的文字描述
//由于这是入口ability,所以图标和文字描述也就是桌面显示的
"startWindowIcon": "$media:icon", //应用启动时的图标
"startWindowBackground": "$color:start_window_background", //应用启动时的图标背景色
"exported": true,
"skills": [ //功能的声明
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
}
}
UIAbility生命周期
- 以微信为例,进入微信会自动创建(Create)一个UIAbility,因为是入口所有会自动设置为前台(Foreground)。
- 当打开小程序或者视频号等独立功能时,会再次创建(Create)一个UIAbility,同时原本的UIAbility会被设置为后台(Background)。查看手机后台可以看到两个微信。
- 当不使用的时候可以直接去除后台(Destroy)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44// src/main/ets/entryability/EntryAbility.ts
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility { //继承了UIAbility
onCreate(want, launchParam) { //当被创建时
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); //hilog是日志
//info是日志级别,还有debug、error等等
//0x0000是用来标识的参数,'testTag'是文字标记,'%{public}s'占位符,public为公开,最后是日志内容
}
onDestroy() { //当被销毁时
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage) { //当WindowStage被创建时
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err, data) => { //打开首页
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() { //当WindowStage被销毁时
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground() { //在前台时
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground() { //在后台时
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}
页面及组件生命周期
- aboutToAppear函数是在组件被创建之后build创建之前触发,可以在这里做一些初始化和数据的准备工作。
- onPageShow函数是当页面被展示的时候会执行,onPageHide函数是当页面被隐藏的时候会执行,onBackPress函数是点击返回的时候触发。三个一起为页面生命周期函数,可以做一些功能性的逻辑。
- aboutToDisappear函数是组件被销毁时触发。可以在这里做一些数据保存等。
- 用push方法跳转页面,并不会销毁组件,而是隐藏,但是replace方法会销毁组件,性能消耗大。
- 子组件不会执行页面生命周期函数。
- For循环刷新渲染会将每个元素都删除重新渲染,需要给每个元素添加标识才可以避免反复渲染。
UIAbility的启动模式
Singleton启动模式
- 每一个UIAbility只存在唯一实例。是默认启动模式。
- 任务列表中只会存在一个相同的UIAbility
- 再次打开UIAbility只是将之前被隐藏的重新显示
standard启动模式
- 每次启动UIAbility都会创建一个新的实例。
- 在任务列表中可能存在一个或多个相同的UIAbility
multiton启动模式
和standard类似,但是每次启动UIAbility都会创建一个新的实例,而旧的会被销毁
specified启动模式
- 每个UIAbility实例可以设置Key标示
- 启动UIAbility时,需要指定Key,存在Key相同实例直接被拉起,不存在则创建新实例
- 在实际应用中,可以在需要多个内容同时使用的情况下使用,例如文档编辑需要打开两个文档,并保留在后台
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41//1. 当前UIAbility调用startAbility方法拉起目标UIAbility
//1.1 获取上下文
context = getContext(this) as common.UIAbilityContext
//1.2 指定要跳转的UIAbility的信息
let want = {
deviceID: '', //deviceId为空表示本设备
bundleName: 'com.example.myapplication', //指定哪个应用的bundleName
abiliyuName: 'DocumentAbility',
moduleName: 'entry', //moduleName非必选
parameters: {
// getInstanceKey:自定义方法,生成目标UIAbility实例的Key
instanceKey: this.getInstanceKey()
}
}
//1.3 尝试拉起目标UIAbility实例
this.context.startAbility(want)
//2. 在AbilityStage的生命周期回调中为目标UIAbility实例生成Key
export default class MyAbilityStage extends AbilityState{
onAcceptWant(want: Want): string {
//判断当前要拉取的是否是DocumentAbility
if(want.abilityName === 'DocumentAbility'){
//根据参数中的instanceKey参数拼接生成一个Key值并返回
return `DocAbility_${want.parameters.instanceKey}`
}
return '';
}
}
//3. 在module.json5配置文件中,通过srcEntry参数指定AbilityStage路径
{
"module":{
"name": "entry",
"type": "entry",
"srcEntry": "./ets/myabilitystage/MyAbilityStage.ts",
...
}
} - 详细可以参考鸿蒙开发文档,因为太复杂了。
评论