一、生命周期的概念
在软件开发领域,生命周期是指一个对象从创建到销毁的完整过程。在操作系统范畴内,对于应用程序或进程而言,生命周期则涵盖从启动到结束的各个阶段。对于 HarmonyOS 应用来说,其生命周期管理尤为关键,它紧密关联着应用的性能表现、用户体验,同时也涉及系统资源的合理分配与调度。
二、HarmonyOS 生命周期主要知识点
(一)UIAbility 生命周期
- onCreate:当应用加载过程中,UIAbility 实例创建完成时,系统会触发此回调。开发者可在此处进行页面初始化操作,如定义变量、加载资源等,为后续的 UI 展示做准备。例如:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化变量 int someVariable = 10; // 加载资源,如布局文件 super.setUIContent(ResourceTable.Layout_ability_main); }
- onWindowStageCreate:在 UIAbility 实例创建完成后,进入前台之前,系统会创建一个 WindowStage。当 WindowStage 创建完成,会进入此回调。开发者可在此设置 UI 加载、订阅 WindowStage 的事件等。示例如下:
@Override public void onWindowStageCreate(WindowStage windowStage) { super.onWindowStageCreate(windowStage); // 设置UI加载 windowStage.getUIContent().setUIContent(ResourceTable.Layout_ability_main); // 订阅事件,如点击事件 Button button = (Button) windowStage.getUIContent().findComponentById(ResourceTable.Id_button); button.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { // 处理点击事件 } }); }
- onForeground:当 UIAbility 的 UI 即将可见时,例如 UIAbility 切换至前台,会触发此回调。开发者可在此申请系统所需资源,或者重新申请在 onBackground 中释放的资源。例如:
@Override public void onForeground(Intent intent) { super.onForeground(intent); // 重新获取摄像头资源 Camera camera = Camera.getInstance(); camera.open(); }
- onBackground:当 UIAbility 的 UI 完全不可见,如切换至后台时触发。在此回调中,开发者可释放 UI 不可见时无用的资源,也可执行一些耗时操作,如保存状态。例如:
@Override public void onBackground(Intent intent) { super.onBackground(intent); // 释放摄像头资源 Camera camera = Camera.getInstance(); camera.release(); // 保存应用状态到本地文件 saveAppState(); }
- onWindowStageDestroy:在 UIAbility 实例销毁之前,会先进入此回调。开发者可在此释放 UI 资源。例如:
@Override public void onWindowStageDestroy(WindowStage windowStage) { super.onWindowStageDestroy(windowStage); // 释放UI相关资源,如图片加载器 ImageLoader.getInstance().releaseResources(); }
- onDestroy:当 UIAbility 实例销毁时触发。在此回调中,开发者应进行系统资源的释放、数据的保存等操作。例如:
@Override protected void onDestroy() { super.onDestroy(); // 关闭数据库连接 DatabaseHelper.getInstance().close(); // 保存用户数据到服务器 saveUserDataToServer(); }
(二)页面生命周期
页面生命周期主要针对被 @Entry 修饰的组件。
- onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景。例如:
@Entry @Component struct MainPage { onPageShow() { // 页面显示时更新数据 this.data = fetchData(); } build() { // 页面构建逻辑 } }
onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。例如
@Entry @Component struct MainPage { onPageHide() { // 页面隐藏时保存临时数据 saveTempData(this.data); } build() { // 页面构建逻辑 } }
- onBackPress:当用户点击返回按钮时触发。例如:
@Entry @Component struct MainPage { onBackPress() { // 处理返回操作,如确认是否退出应用 return confirmExitApp(); } build() { // 页面构建逻辑 } }
(三)组件生命周期
- aboutToAppear:在创建自定义组件的新实例后,执行其 build () 函数之前执行。开发者可在此函数中改变状态变量,更改将在后续执行 build () 函数中生效。例如:
@Component struct CustomComponent { @State data: string; aboutToAppear() { this.data = "Initial data"; } build() { // 组件构建逻辑,使用this.data } }
- aboutToDisappear:在自定义组件销毁之前执行。注意,不允许在此函数中改变状态变量,特别是 @Link 变量的修改可能会导致应用程序行为不稳定。例如:
@Component struct CustomComponent { aboutToDisappear() { // 清理组件相关资源,如定时器 clearTimeout(this.timer); } build() { // 组件构建逻辑 } }
三、扩展技术点
(一)生命周期状态持久化
在应用从后台切换回前台时,为了给用户提供连贯的体验,可能需要保存和恢复应用状态。在 onBackground 回调中,可以将关键数据(如用户当前浏览位置、未提交的表单数据等)保存到本地存储或者通过分布式数据服务进行跨设备存储。例如,使用 Preferences 工具保存简单数据:
Preferences preferences = Preferences.createWithMode(this, "app_preferences", Preferences.PRIVATE); preferences.putInt("current_page_index", currentPageIndex); preferences.flush();
在 onCreate 或 onForeground 中再读取恢复:
Preferences preferences = Preferences.createWithMode(this, "app_preferences", Preferences.PRIVATE); int savedPageIndex = preferences.getInt("current_page_index", -1); if (savedPageIndex != -1) { // 恢复页面状态 }
(二)进程优先级与生命周期关系
HarmonyOS 系统会根据应用的生命周期状态来调整其进程优先级。处于前台运行的应用(UIAbility 处于 onForeground 状态)具有较高优先级,系统会优先保障其资源供应,避免被系统杀死。而处于后台的应用(UIAbility 处于 onBackground 状态),进程优先级降低。如果系统资源紧张,后台应用进程可能会被终止。开发者需要注意,在进程被终止前,确保关键数据已保存,并且在应用重新启动时能够正确恢复状态。例如,在 onDestroy 中可以进行一些紧急的数据同步操作到服务器,防止数据丢失。
(三)多窗口模式下的生命周期变化
当应用支持多窗口模式时,其生命周期会有特殊情况。例如,当一个应用的窗口从全屏切换到分屏或悬浮窗模式时,UIAbility 的 onConfigurationChanged 回调会被触发,开发者可以在此回调中调整 UI 布局以适应不同窗口大小和比例。同时,不同窗口之间的焦点切换也会影响生命周期,获得焦点的窗口对应的 UIAbility 会进入 onForeground,失去焦点的则进入 onBackground。例如:
@Override public void onConfigurationChanged(Configuration configuration) { super.onConfigurationChanged(configuration); if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) { // 切换为横屏时调整布局 windowStage.getUIContent().setUIContent(ResourceTable.Layout_landscape_ability_main); } else { // 切换为竖屏时调整布局 windowStage.getUIContent().setUIContent(ResourceTable.Layout_portrait_ability_main); } }
(四)与系统服务交互时的生命周期考量
应用在使用系统服务(如定位服务、推送服务等)时,其生命周期也会产生关联影响。以定位服务为例,通常在 onCreate 或 onForeground 中申请定位权限并启动定位服务,在 onBackground 或 onDestroy 中停止定位服务以节省电量和系统资源。如果在应用进入后台后仍持续使用定位服务,可能会导致电池功耗增加,并且可能违反系统对后台应用行为的限制。例如:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); if (locationManager != null) { if (hasPermission()) { locationManager.requestLocationUpdates(LocationRequest.create() .setInterval(5000) .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY), new LocationCallback() { @Override public void onLocationUpdated(Location location) { // 处理定位更新 } }, getMainExecutor()); } }
在 onDestroy 中:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); if (locationManager != null) { locationManager.removeUpdates(locationCallback); }
四、应用跳转与生命周期
当进行应用跳转时,原应用的 UIAbility 会进入 onBackground 回调,资源释放等操作会在此进行。而目标应用的 UIAbility 则会依次经历 onCreate、onWindowStageCreate、onForeground 等回调,完成初始化并进入前台展示。在页面跳转时,原页面触发 onPageHide,目标页面触发 onPageShow。例如,从 A 页面跳转到 B 页面,A 页面执行 onPageHide,B 页面执行 onPageShow。如果 B 页面是首次创建,还会执行相关组件的 aboutToAppear 以及自身的 onInit 等生命周期方法。
五、第一次加载页面时的生命周期
应用第一次加载页面时,会经历较为复杂的生命周期流程。首先,UIAbility 会触发 onCreate,完成基本初始化;接着 onWindowStageCreate 被触发,用于设置 UI 等操作;之后进入 onForeground,使应用可见。对于页面而言,先执行页面自身的初始化方法(如相关框架下的 onInit 等),然后资源加载完成后执行类似 onReady 的回调,最后执行 onPageShow,将页面展示给用户。同时,页面内的组件会依次触发 aboutToAppear,在组件渲染完成后,如果组件状态有变化,可能会再次触发相关更新逻辑。例如,一个包含列表组件的页面,列表组件的每个子项在创建时都会触发 aboutToAppear,在页面完全展示给用户前,完成所有相关生命周期方法的执行。
#HarmonyOS应用开发工具##Ark-TS UI#