3. Page Ability基础:Page Ability生命周期

说实话,刚接触鸿蒙开发那会儿,我最头疼的就是生命周期。你想想看,一个页面从创建到销毁,中间经历了什么?什么时候该初始化数据?什么时候该释放资源?搞不清楚这些,应用就容易出各种奇奇怪怪的bug。

今天我就带你彻底搞懂Page Ability的生命周期。这玩意儿说白了,就是系统管理页面的一套规则。你只要摸清了这套规则,写出来的应用就会特别稳。

3.1 生命周期总览

Page Ability有6个核心生命周期回调。我习惯把它们分成三组来记:

  • 创建与销毁:onStart、onStop
  • 可见与不可见:onForeground、onBackground
  • 活跃与不活跃:onActive、onInactive

嗯,这样分组记忆起来特别清晰。咱们先看一张流程图,把整体脉络理清楚。

Page Ability 生命周期流程图 启动Ability onStart() onForeground() onActive() onInactive() onBackground() 重新回到前台 onInactive() onStop()

3.2 各生命周期详解

onStart() — 页面初始化

这是Page Ability的第一个回调。说白了,就是页面刚被创建时调用的。我一般在这里做三件事:

  • 加载布局文件
  • 初始化一些全局变量
  • 设置基本的UI配置

核心要点:onStart只调用一次。如果页面被销毁后重新创建,会再次调用。

@Override
protected void onStart(Intent intent) {
    super.onStart(intent);
    // 设置布局
    super.setUIContent(ResourceTable.Layout_ability_main);
    // 初始化数据
    initData();
    // 设置点击事件
    initListener();
}

我的小习惯:我会在onStart里打一个日志,方便调试时确认页面是否被重建。比如:HiLog.info(LABEL, "onStart called");

onActive() — 页面获得焦点

当页面进入前台并且可以和用户交互时,就会调用onActive。我在项目中遇到过一个问题:用户切到其他应用再切回来,页面数据需要刷新。这时候onActive就是最佳时机。

@Override
protected void onActive() {
    super.onActive();
    // 刷新页面数据
    refreshData();
    // 开始动画或定时任务
    startTimer();
}

onInactive() — 页面失去焦点

这个回调表示页面即将失去焦点。为什么会失去焦点?可能是弹出了一个对话框,也可能是用户按了Home键。

注意:onInactive调用后,页面可能进入onBackground,也可能只是短暂失去焦点后又重新获得。所以不要在这里做太重的操作。

@Override
protected void onInactive() {
    super.onInactive();
    // 暂停动画
    pauseAnimation();
    // 保存临时数据
    saveTempData();
}

onForeground() 与 onBackground()

这两个回调成对出现。onForeground表示页面可见了,onBackground表示页面不可见了。

你想想看,用户按了Home键,页面就进入后台了。这时候onBackground会被调用。等用户再切回来,onForeground就会触发。

回调 触发时机 典型用途
onForeground 页面从后台回到前台 重新获取资源、刷新UI
onBackground 页面进入后台 释放资源、保存状态
@Override
protected void onForeground() {
    super.onForeground();
    // 重新连接WebSocket
    reconnectWebSocket();
}

@Override
protected void onBackground() {
    super.onBackground();
    // 断开不必要的连接
    disconnectWebSocket();
}

onStop() — 页面销毁

这是最后一个回调。页面被销毁时调用,比如用户按了返回键,或者系统需要回收内存。

避坑指南:我曾经在onStop里忘记取消注册广播接收器,结果页面销毁后还在接收广播,导致内存泄漏。所以一定要在这里做好清理工作。

@Override
protected void onStop() {
    super.onStop();
    // 取消注册
    unregisterReceiver();
    // 释放大对象
    bitmap.recycle();
    // 关闭数据库连接
    closeDatabase();
}

3.3 生命周期应用场景

光知道回调顺序还不够,关键是要知道在什么场景下用哪个回调。我总结了几个常见场景:

场景一:页面数据刷新

用户从其他页面返回时,需要刷新列表数据。这时候用onActive最合适。因为onActive表示页面已经可见且可交互。

场景二:视频播放暂停

用户切到后台时,视频应该暂停播放。在onBackground里暂停,在onForeground里恢复播放。嗯,这样用户体验最好。

场景三:表单数据保存

用户正在填写表单,突然来了个电话。这时候在onInactive里保存草稿,等用户回来再恢复。我曾经因为这个功能被用户夸过,说应用很贴心。

场景四:资源释放

页面销毁时,一定要在onStop里释放所有资源。比如关闭文件流、取消网络请求、注销监听器等。不然很容易造成内存泄漏。

我的经验:我习惯在onStart里做资源申请,在onStop里做资源释放。这样成对出现,不容易遗漏。你可以试试这个套路。

3.4 生命周期调用顺序总结

咱们来捋一遍完整的调用顺序:

  1. 首次启动:onStart → onForeground → onActive
  2. 按Home键:onInactive → onBackground
  3. 从后台返回:onForeground → onActive
  4. 按返回键:onInactive → onBackground → onStop
  5. 系统回收:onInactive → onBackground → onStop

说白了,你只要记住一个核心原则:谁申请谁释放,成对出现。这样写出来的代码就不会有生命周期相关的问题。

好了,这一章的内容就到这里。生命周期这块儿,你多写几个页面自然就熟练了。刚开始可能会觉得有点绕,但用多了就会发现,其实就那么回事儿。


专注资料整理