
应用生命周期适配 原创
1 应用生命周期适配
HarmonyOS NEXT游戏启动、运行、销毁时分别对应不同的生命周期,游戏适配需将引擎在Native侧的生命周期与应用的生命周期绑定,实现不同状态之间的切换。游戏场景下,应用主要生命周期时序大致如下图所示:
cke_89157.png
HarmonyOS NEXT游戏通过UIAbility组件与用户进行交互,当用户打开、切换应用以及关闭应用时,应用中的UIAbility实例会在其生命周期的不同状态之间转换。
在Stage模型下,应用主窗口由UIAbility创建并维护生命周期,UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态,与显示相关的状态通过WindowStage的事件暴露给开发者。
新建DevEco Studio工程时,将在entry/src/main/ets/entryability目录下默认生成UIAbility,其中包含常用的生命周期回调,其中nativeAppLifecycle是引擎在Native侧的生命周期。
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import nativeRender from 'libnativerender.so';
export enum ContextType {
APP_LIFECYCLE,
PAGE_LIFECYCLE,
}
const nativeAppLifecycle = nativeRender.getContext(ContextType.APP_LIFECYCLE);
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
nativeAppLifecycle.onCreate();
}
onDestroy(): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
nativeAppLifecycle.onDestroy();
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err) => {
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.');
});
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
nativeAppLifecycle.onForeground();
}
onBackground(): void {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
nativeAppLifecycle.onBackground();
}
};
常用的UIAbility生命周期回调
- onCreate():在应用加载过程中,UIAbility实例创建完成时触发Create状态,此时系统会调用onCreate()回调。可以在该回调中进行页面初始化操作,例如变量定义资源加载等,用于后续的UI展示。
- onDestroy():在销毁时回调,执行资源清理等操作。
- onForeground():当应用从后台转到前台时触发。
- onBackground():当应用从前台转到后台时触发。
在UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。
常用的WindowStage生命周期回调
- onWindowStageCreate():当WindowStage创建完成后调用;可以在该回调中设置UI加载、设置WindowStage的事件订阅。
- onWindowStageDestroy():当WindowStage销毁后调用。
cke_12660.png
相关文档:
|
Page的生命周期
应用的UI页面可由一个或者多个自定义组件组成。一般基本页面需由@Entry @Component这两个组件进行装饰。
- @Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期。
- @Component:@Component装饰的UI单元为自定义组件,可组合多个系统组件实现UI的复用
在WindowStage的onWindowStageCreate()回调中通过loadContent()方法设置应用要加载的主页面,并进行页面的加载。 |
每个Stage模型的DevEco Studio工程会默认创建一个Page(entry/src/main/ets/pages/Index.ets)页面生命周期,被@Entry装饰的组件生命周期可提供以下生命周期接口:
属性 | 类型 | 触发时机 |
onPageShow | () => void | 页面每次显示时触发。 |
onBackPress | () => boolean | 返回按钮动作,当用户点击返回按钮时触发。
|
onPageHide | () => void | 页面每次隐藏时触发一次。 |
组件生命周期,被@Component装饰的自定义组件的生命周期可提供以下生命周期接口:
属性 | 类型 | 触发时机 |
aboutToAppear | () => void | 页面数据初始化完成时触发,只触发一次。 |
aboutToDisappear | () => void | 在自定义组件即将析构销毁时执行。 |
被@Entry和@Component装饰的页面中可定义如下的生命周期接口的调用顺序如下:
cke_22468.png
Index.ets页面如下:
// Index.ets
import nativeRender from 'libnativerender.so';
export enum ContextType {
APP_LIFECYCLE,
PAGE_LIFECYCLE,
}
const nativePageLifecycle = nativeRender.getContext(ContextType.PAGE_LIFECYCLE);
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
onPageShow(): void {
console.log('[LIFECYCLE-Page] onPageShow');
nativePageLifecycle.onPageShow();
}
// back operation
onBackPress() {
console.log('[LIFECYCLE-Page] onBackPress');
// 向子线程发送消息,处理侧滑事件
this.subWorker.postMessage({ type: "exit" });
}
onPageHide(): void {
console.log('[LIFECYCLE-Page] onPageHide');
nativePageLifecycle.onPageHide();
}
// 组件生命周期
aboutToAppear() {
console.info('MyComponent aboutToAppear');
}
// 组件生命周期
aboutToDisappear() {
console.info('MyComponent aboutToDisappear');
}
build() {
// build()函数下的根节点唯一且必要,且必须为容器组件
Row() {
XComponent({
id: 'xcomponentId',
type: 'surface',
libraryname: 'nativerender',
})
.onLoad((context) => {
this.context = context;
})
}
.height('100%')
}
}
|
XComponent组件生命周期
XComponent组件作为一种绘制组件,通常用于满足开发者较为复杂的自定义绘制需求。开发者可使用XComponent组件来进行EGL/OpenGLES渲染的开发和媒体数据写入。
若对XComponent进行Native 开发,需要在ArkTS侧和Native侧进行开发。Native XComponent是XComponent组件提供在Native侧的实例,可作为JS层和Native层XComponent绑定的桥梁。在ArkTS侧使用XComponent组件并选择surface;在Native侧开发需对ArkUI XComponent所持有的surface和触摸事件注册相应的回调。
若在主页面绘制图形,需在Native侧注册surface生命周期和触摸事件回调。借助XComponent进行EGL/OpenGLES的渲染开发步骤见渲染一节。
ArkTS侧代码如下,其中有onLoad()和onDestroy()事件。
XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'nativerender' })
.onLoad((context) => {})
.onDestroy(() =>
Native侧surface生命周期相关Callback的定义如下:
成员变量名称 | 描述 |
OH_NativeXComponent_Callback::OnSurfaceCreated | surface创建成功后触发。 |
OH_NativeXComponent_Callback::OnSurfaceChanged | surface发生变化后触发。 |
OH_NativeXComponent_Callback::OnSurfaceDestroyed | surface销毁时触发。 |
OH_NativeXComponent_Callback::DispatchTouchEvent | 触摸事件被触发时调用。 |
XComponent组件ArkTS层和Native层的时序对应如下:
1. onLoad事件
定义:组件加载完成时回调事件。
触发时刻:当XComponent准备好surface后触发。
参数context:context上挂载了暴露在模块上(nativerender.so)的Native方法。
XComponent中的libraryname的作用类似于import某个so模块,因此context的使用方法类似于利用 import context from "libnativerender.so"直接加载模块后获得的context实例时序:onLoad事件的触发和surface相关,其和Native侧的OnSurfaceCreated的时序如下图:
cke_43686.png
2. 组件改变事件
定义:当组件UI发生变化引起重绘时的回调事件。
触发时刻:当XComponent的surface发生变化时,会触发OnSurfaceChangedCB对当前的XComponent持有的surface对象进行重新绘制,使得其生成相应的内容重新展示出来。例如当一个surface的尺寸、模式或者其他位置发生变化时(常见于折叠屏、屏幕旋转),OnSurfaceChangedCB就会被调用。
3. onDestroy事件
定义:插件卸载完成时回调事件。
触发时刻:XComponent组件被销毁时触发与一般ArkUI的组件销毁时机一致。
时序:其和Native侧的OnSurfaceDestroyed的时序如下图:
cke_48555.png
XComponent生命周期适配详见渲染及窗口开发章节。
参考文档
- 页面和自定义组件的生命周期
- build函数
- 声明式UI描述
- XComponent:XComponent组件的介绍。
- XComponent开发指导:描述XComponent的生命周期和开发步骤。
- Native XComponent。
更多问题可关注:
鸿蒙游戏官方网站:已有游戏移植-鸿蒙游戏-华为开发者联盟
公开课:华为开发者学堂
