对Android Activity的崩溃恢复总是糊里糊涂的, 今天写一个demo测试一下
前提
a. 所有启动都是标准启动
b. Main Test启动模式默认, 也就是standard, Test2为 singleInstance
c. Main = MainActivity, Test = DpActivityManagerTestActivity ,Test2 = DpActivityManagerTestActivity2
操作
1.正常启动Acitvity, 启动顺序: Main->Test->Test2->Test 创建过程如下:
03-15 17:44:11.677 12033-12033/com.dp.kookong_uilib_sample D/App: App: onCreate, pid = 12033
03-15 17:44:11.763 12033-12033/com.dp.kookong_uilib_sample D/MainActivity: DpActivityManagerTestActivity: onCreate
03-15 17:44:14.295 12033-12033/com.dp.kookong_uilib_sample D/DpActivityManagerTestActivity: DpActivityManagerTestActivity: onCreate
03-15 17:44:16.739 12033-12033/com.dp.kookong_uilib_sample D/DpActivityManagerTestActivity2: DpActivityManagerTestActivity2: onCreate
03-15 17:44:17.837 12033-12033/com.dp.kookong_uilib_sample D/DpActivityManagerTestActivity: DpActivityManagerTestActivity: onCreate
复制代码
2.在第二个Test触发NPE, 在三星手机会提示 XXX已经停止, 然后可以选择重启App点击重启后 (在努比亚手机上直接重启Test)
03-15 17:44:35.018 12069-12069/com.dp.kookong_uilib_sample D/App: App: onCreate, pid = 12069
03-15 17:44:35.125 12069-12069/com.dp.kookong_uilib_sample D/DpActivityManagerTestActivity: DpActivityManagerTestActivity: onCreate复制代码
App完成了重启, 此时是新的进程了, 但是只是恢复了Test, 现在App有两个test, 会是哪一个呢?往下看.
3.点击返回
03-15 17:45:04.613 12069-12069/com.dp.kookong_uilib_sample D/MainActivity: MainActivity: onCreate复制代码
返回到了Main, 确认恢复的Test实际上是从Main打开的那个Test. 那么Test2和崩溃的那个Test在哪里呢?
4.再次点击返回, 这个行为和App正常运行是一样的
03-15 17:45:42.944 12069-12069/com.dp.kookong_uilib_sample D/DpActivityManagerTestActivity2: DpActivityManagerTestActivity2: onCreate
复制代码
5.再次点击返回, App退出, 没有看到崩溃的Test, 也就是系统不会恢复他.
分析:
A. step 1 操作以后, Activity栈的情况如下, 绿色为同一个ActivityTask, Test2单独自己的Task, Test2的Task在后台.
如果此时从Test1点击返回, 可以返回到第一个那个Test1, 然后是Main, 然后是Test2
B. 最顶部的Test1因为NPE崩溃以后, Android系统实际上把Activity恢复到了第一个Test1, 此时Test2的Task依然在后台, 注意, 此时Main和Test2 都没有
onCreate
C. 在Test1点击返回, 系统会创建Main, 同理在Main点击返回, 系统onCreate Test2, Test2点击返回, App退出
结论:
1.Activity崩溃后, Android系统会重建ActivityTask, 从Task中移除异常崩溃的那个Activity, Task中倒数第二个Activity展示出来, 执行onCreate.
Task中其他的Activity不会执行onCreate (有没有大神从源码角度分析一下, 待恢复的Activity有没有在内存中)
2. ActivityTask恢复也会恢复所有的ActivityTask, 以及前后台关系.
3. 单例, 静态变量等的初始化, 不要放到你的StartActivity中,这样不靠谱. 建议懒加载, 如果非要使用, 可以放到App中. 或者直接注册崩溃Handler, 自己把进程kill掉.用户重新启动App(这也不是很靠谱, 引申中会提出)
引申:
测试遇到过在某些手机(MIUI系统概率高)中, App后台以后一段时间, 再次启动App, 会恢复到之前停留的Activity, 但是单例, 静态变量却都没了, 最后爆出NPE. 应该也和ActivityTask的崩溃恢复有关系. 此种情况, 可能不会走崩溃的Handler, 故,第三条可能还是粗体部分靠谱. 此种情况太难复现, 抱歉只是推论出的结论.