3. Page Ability基础:Page Ability生命周期
说实话,刚接触鸿蒙开发那会儿,我最头疼的就是生命周期。你想想看,一个页面从创建到销毁,中间经历了什么?什么时候该初始化数据?什么时候该释放资源?搞不清楚这些,应用就容易出各种奇奇怪怪的bug。
今天我就带你彻底搞懂Page Ability的生命周期。这玩意儿说白了,就是系统管理页面的一套规则。你只要摸清了这套规则,写出来的应用就会特别稳。
3.1 生命周期总览
Page Ability有6个核心生命周期回调。我习惯把它们分成三组来记:
- 创建与销毁:onStart、onStop
- 可见与不可见:onForeground、onBackground
- 活跃与不活跃:onActive、onInactive
嗯,这样分组记忆起来特别清晰。咱们先看一张流程图,把整体脉络理清楚。
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 生命周期调用顺序总结
咱们来捋一遍完整的调用顺序:
- 首次启动:onStart → onForeground → onActive
- 按Home键:onInactive → onBackground
- 从后台返回:onForeground → onActive
- 按返回键:onInactive → onBackground → onStop
- 系统回收:onInactive → onBackground → onStop
说白了,你只要记住一个核心原则:谁申请谁释放,成对出现。这样写出来的代码就不会有生命周期相关的问题。
好了,这一章的内容就到这里。生命周期这块儿,你多写几个页面自然就熟练了。刚开始可能会觉得有点绕,但用多了就会发现,其实就那么回事儿。