本篇内容 UIAbility组件的学习
从本篇节开始,将进入到ArkTS开发阶段的学习
一、知识储备
1. UIAbility组件是一种包含了UI界面的应用组件,
- 主要用于和用户交互。
- 是系统调度的基本单元;
- 一个UIAbility组件可以由多个页面来实现一个功能模块,
- 每个UIAbility组件实例,都对应一个最近任务列表中的任务.
- 要想使UIAbility正常工作,需要在module.json5配置文件中的abilities标签中声明其名称、入口等相关信息
{
"module": {
//...
"abilities": [
{
"name": "EntryAbility",// UIAbility组件的名称
"srcEntry": "./ets/entryability/EntryAbility.ts",// UIAbility组件的代码路径
"description": "$string:EntryAbility_desc", // UIAbility组件的描述信息
"icon": "$media:icon", // UIAbility组件的图标
"label": "$string:EntryAbility_label",// UIAbility组件的标签
"startWindowIcon": "$media:icon",// UIAbility组件启动页面图标资源文件的索引
"startWindowBackground": "$color:start_window_background",// UIAbility组件启动页面背景颜色资源文件的索引
"exported": true,
//...
}
]
}
2. 生命周期
- Create 实例被创建时,onCreate只触发一次
- WindowStageCreate 当实例可见之前系统会创建一个windowStage,创建完成后,会触发onWindowStageCreate回调,可以在回调中设置ui、windowStage事件等相关处理
- Foreground 当实例可见时, onForeground会触发
- Background 当实例不可见时,onBackground会触发
- WindowStageDestroy 在实例销毁之前 ,会先进入onWindowStageDestroy回调,可以在回调里释放ui资源等
- Destroy 实例被销毁时, onDestroy只触发一次
3. 启动模式
① 有三种启动模式,singleton(单实例)
- 每次调用**startAbility()**函数时,如果进程中有该类型的实例存在,则直接复用。不会创建新的实例。
- 如果需要使用singleton启动模式,在module.json5配置文件中的"launchType"字段配置为"singleton"即可。
② multiton(多实例)
- 每次调用**startAbility()**函数时,不管进程中是否存在该类型实例,都会直接创建一个新的实例。
- multiton启动模式的开发使用,在module.json5配置文件中的"launchType"字段配置为"multiton"即可。
③ specified(指定实例)
- 针对某些特殊场景使用(例如文档应用中每次新建希望是新建的空白文档实例,重复打开一个已保存的文档则希望是打开同一个实例)
- 在创建实例时,绑定一个唯一的字符串key,后续每次调用startAbility函数带上key,如果匹配到此key则直接拉起绑定的实例,否则创建一个新的实例。
- 在FuncAbility中,将module.json5配置文件的"launchType"字段配置为"specified"。
- 调用时的示例代码如下
let want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
moduleName: 'module1', // moduleName非必选
parameters: { // 自定义信息
instanceKey: getInstance(),
},
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(want).then(() => {
// ...
}).catch((err) => {
// ...
})
export default class MyAbilityStage extends AbilityStage {
onAcceptWant(want): string {
// 在被调用方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值
// 当前示例指的是module1 Module的FuncAbility
if (want.abilityName === 'FuncAbility') {
// 返回的字符串Key标识为自定义拼接的字符串内容
return `ControlModule_EntryAbilityInstance_${want.parameters.instanceKey}`;
}
return '';
}
}
4.UIAbility的基本用法
windowStage.loadContent('page/Index', (err, data)=>{
// ...
});
onCreate(want, launchParam) {
let context = this.context;// 在Ability被创建的回调中获取
}
import common from '@ohos.app.ability.common'; //引用common依赖的方式获取
private context = getContext(this) as common.UIAbilityContext; //
5. UIAbility组件与UI的数据同步
//在ability中注册
eventHub.on('event', this.back);
eventHub.on('eventBack', (...data) => {
console.error('我被执行了')
this.onBackground()
})
//在page中调用
context.eventHub.emit('event')
- 使用globalThis进行数据同步, 其为全局对象
//在ability中定义
globalThis.initTitle = '我是测试标题'
//在ability、page中随处调用
console.error(`我读取到了:${globalThis.initTitle}`)
二、效果一览
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b89d3243f542423d9e131bfb9d54f8f3.gif#pic_center)
三、源码分析讲解
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', '我被创建了');
globalThis.initTitle = '我是测试标题'
}
onDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', '我被销毁了');
}
/*****************在这里定义LocalStorage*****************/
args: Record<string, Object> = {
'height': 111, 'age': 10, 'name': '小明', sex: '未知'
};
storage: LocalStorage = new LocalStorage(this.args)
onWindowStageCreate(windowStage: window.WindowStage) {
hilog.info(0x0000, 'testTag', '%{public}s', '系统接管创建');
windowStage.loadContent('pages/AbilityIndex', this.storage) //把localStorage实例传递过去
}
/*****************在这里定义LocalStorage*****************/
onWindowStageDestroy() {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', '系统接管销毁');
}
onForeground() {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', '我要可见了');
}
onBackground() {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', '我不可见了');
}
}
import common from '@ohos.app.ability.common';
@Entry
@Component
struct AbilityIndex {
private context = getContext(this) as common.UIAbilityContext;
build() {
Row() {
Column() {
Button() {
Text("跳转Ability")
.fontColor(Color.Blue)
.fontSize(55)
.fontWeight(FontWeight.Bold)
}.type(ButtonType.Capsule)
.onClick(() => {
let want = {
deviceId: '',
bundleName: 'com.aji.first',
abilityName: 'SecondAbility',
moduleName: '',
parammeters: {
instanceKey: ""
}
}
this.context.startAbility(want).then(() => {
console.info('startSecondAbility()')
}).catch((err) => {
console.error(`err.code is ${err.code}`)
})
})
}.width('100%')
}.width('100%')
}
}
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
export default class SecondAbility extends UIAbility {
onCreate(want, params) {
let eventHub = this.context.eventHub;
eventHub.on('event', this.back);
eventHub.on('eventBack', (...data) => {
console.error('我被执行了')
this.onBackground()
})
console.error(`我读取到了:${globalThis.initTitle}`)
}
onWindowStageCreate(windowStage: window.WindowStage) {
windowStage.loadContent("pages/second/SecondIndex")
}
back(...data){
console.error('我被执行了')
this.onBackground()
}
}
import common from '@ohos.app.ability.common'
@Entry
@Component
struct SecondIndex{
build(){
Row(){
Column(){
Button(){
Text('我就是第二个Ability的主页面')
.fontSize(66)
.fontWeight(FontWeight.Bold)
}
.width('60%')
.onClick(()=>{
let context = getContext(this) as common.UIAbilityContext;
context.eventHub.emit('event')
})
}.width('100%')
}.width('100%')
}
aboutToAppear(){
console.error(`我读取到了:${globalThis.initTitle}`)
}
}