应用生命周期适配 原创
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。
 
更多问题可关注:
鸿蒙游戏官方网站:已有游戏移植-鸿蒙游戏-华为开发者联盟
公开课:华为开发者学堂





















