应用生命周期适配 原创

游戏技术分享
发布于 2025-5-7 16:00
浏览
0收藏

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这两个组件进行装饰。

  1. @Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期。
  2. @Component:@Component装饰的UI单元为自定义组件,可组合多个系统组件实现UI的复用

应用生命周期适配-鸿蒙开发者社区


   在WindowStage的onWindowStageCreate()回调中通过loadContent()方法设置应用要加载的主页面,并进行页面的加载。

每个Stage模型的DevEco Studio工程会默认创建一个Page(entry/src/main/ets/pages/Index.ets)页面生命周期,被@Entry装饰的组件生命周期可提供以下生命周期接口:

属性

类型

触发时机

onPageShow

() => void

页面每次显示时触发。

onBackPress

() => boolean

返回按钮动作,当用户点击返回按钮时触发。

  • 返回true表示页面自己处理返回逻辑。
  • 返回false表示使用默认的返回逻辑。
  • 无返回值是默认false。

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%')   
  }   
}

应用生命周期适配-鸿蒙开发者社区


  • nativePageLifecycle就是Native侧Page的生命周期,需要在引擎侧定义。
  • 需在build方法中描述UI。自定义组件中提供了一个build函数,开发者需在该函数内以链式调用的方式进行基本的UI描述,所有声明在build()函数的语言被统称为UI描述语言。
  • @Entry装饰的自定义组件,其  build()函数下的根节点唯一且必要,且必须为容器组件,其中ForEach禁止作为根节点。
    @Component装饰的自定义组件,其build()函   数下的根节点唯一且必要,可以为非容器组件。

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生命周期适配详见渲染及窗口开发章节。

参考文档


更多问题可关注:

鸿蒙游戏官方网站:​​已有游戏移植-鸿蒙游戏-华为开发者联盟​

公开课:​​华为开发者学堂​

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
收藏
回复
举报
回复
    相关推荐