请详细描述 Activity 从创建到销毁的完整生命周期回调顺序及其触发场景
解读
面试官想确认两点:
- 你是否能把 7 大生命周期方法按“官方契约”顺序背出来;
- 你是否知道每个回调背后真正的“系统行为”与“业务含义”,而不是死记硬背。
国内大厂面试常追问“onStart 与 onResume 区别”“onPause 能否做耗时”“旋转屏幕到底走了谁”等,答错一个细节就可能被判定为“只写过 Demo”。
知识点
- 官方 7 大方法:onCreate → onStart → onResume → onPause → onStop → onDestroy,外加 onRestart。
- 系统行为:ActivityRecord、Task、Process 优先级、Configuration Change、ActivityThread H 消息、Instrumentation 回调。
- 国内特殊场景:
① 厂商后台管控导致“秒级 onStop/onDestroy”;
② 折叠屏、深色模式、语言切换等 Configuration Change 不走 onRestart;
③ 微信、支付宝“单任务多 Activity”复用 Task 的诡异栈序;
④ 小米/华为“权限弹窗”触发透明 Activity 导致 onPause 不 onStop。 - 高频坑:
- onPause 里做 10 ms 以上工作会拖慢新 Activity 启动速度,用户感知“点击延迟”;
- onSaveInstanceState 在 onStop 之后(API 28+)调用,勿再存大对象;
- 透明主题 Activity 只走 onPause 不走 onStop;
- 后台进程被 LRU 回收,回到前台会重走 onCreate 无 onRestart。
答案
完整顺序与触发场景(按国内真机实测结论):
-
首次冷启动
点击 Launcher 图标 → Zygote fork 进程 →
ActivityThread.handleMessage(LAUNCH_ACTIVITY) →
onCreate(首次创建,setContentView 初始化 View 树,savedInstanceState 为 null)
→ onStart(Activity 可见但仍在后台,Window 已 add,Surface 未置顶)
→ onResume(进入“前台”状态,InputDispatcher 把事件通道切到本 Activity,16 ms 帧率开始统计) -
跳转到新 Activity(非透明)
A.onPause(B 未 onCreate 前执行,必须轻量,否则 B 启动慢)
→ B.onCreate → B.onStart → B.onResume
→ A.onStop(B 完全覆盖且系统认为 A 不可见后触发,此时 A 可能被缓存到 Task 栈) -
按返回键回到 A
B.onPause → A.onRestart(仅当 A 未被销毁) → A.onStart → A.onResume
→ B.onStop → B.onDestroy -
横竖屏旋转(android:configChanges 未声明)
系统先调用 onPause → onStop → onSaveInstanceState → onDestroy
→ 立即重新 onCreate(带非空 savedInstanceState) → onStart → onResume
注意:国内 ROM 若开启“锁定方向”则不会触发;折叠屏展开/合拢走同一套流程。 -
用户按 Home 进后台
onPause → onStop(不会 onDestroy,进程进入 LRU 列表,国内 5~30 min 可能被杀) -
从最近任务切回
进程仍在:onRestart → onStart → onResume
进程被杀:Application.onCreate 重新走 → 新实例 onCreate(带 savedInstanceState) -
finish() 或系统回收
先 onPause → onStop → onDestroy(释放 Window、Surface、Bitmap 缓存) -
透明主题 Activity 启动
只触发 A.onPause,不触发 A.onStop;用户看得到的底层 A 仍“可见”。 -
国内厂商“后台清理”
直接杀进程,不会走任何生命周期;下次启动等价冷启动,但系统会把 savedInstanceState 通过 ActivityClientRecord 恢复,开发者感知为“onCreate 带 Bundle”。
口诀:
Create 建,Start 见,Resume 前;
Pause 停,Stop 隐,Destroy 完;
Restart 只在前台复活间。
拓展思考
-
如何在 onPause 里把 200 ms 的持久化任务降到 5 ms?
答:使用 ViewModel+SavedStateHandle 做轻量状态落地,真正 IO 丢到 Room 的协程或 WorkManager 后台任务;onPause 只提交一条数据库事务的 begin,不等待 end。 -
为什么国内项目普遍重写 onConfigurationChanged 而不是让它重建?
答:重建会导致 WebView 重载、视频播放闪黑、直播 SDK 重新拉流;代价是需手动 reload 资源,需权衡内存泄漏风险。 -
面试反问技巧:
“贵业务对横竖屏旋转要求如何?是否有折叠屏适配专项?”
把生命周期聊到业务痛点,展示你不仅懂流程,还能帮团队省 200 ms 启动时长、降低 2% 后台被杀率,才是高分回答。