Activity Lifecycle & LaunchMode

88 阅读2分钟

20190419161012863.png

## Activity_A 打开 Activity_B 时会有哪些生命周期回调
当 Activity_B 的 launchMode 为 Standard 或者 Activity_B 没有可复用的实例时:
    A.onPause -> B.onCreate -> B.onStart -> B.onResume -> A.onStop -> A.onSaveInstanceState
当 Activity_B 的 launchMode 为 SingleTop 且 Activity_B 已经在栈顶时(如点击通知栏、连点):
    B.onPause -> B.onNewIntent -> B.onResume
当 Activity_B 的 launchMode 为 SingleInstance 或 SingleTask 且 Activity_B 有可复用的实例时:
    A.onPause -> B.onRestart -> B.onStart -> B.onNewIntent -> B.onResume -> A.onStop -> A.onSaveInstanceState

Dialog 对生命周期的影响

生命周期回调都是 AMS 通过 Binder 通知应用进程调用的,而 Dialog、Toast、PopupWindow 本质上都直接是通过 WindowManager.addView 来显示的(没有经过 AMS),所以不会对生命周期有任何影响 如果是启动一个 Theme 为 Dialog的Activity , 则生命周期为:A.onPause -> B.onCreate -> B.onStart -> B.onResume,注意这边没有前一个 Activity 不会回调 onStop,因为只有在 Activity 切到后台不可见才会回调 onStop

onActivityResult 回调时机

B.onPause -> A.onActivityResult -> A.onRestart -> A.onStart -> A.onResume

ANR触发条件

Service TimeOut:  Service未在规定时间执行完成
    普通服务-前台进程 20s,普通服务-后台进程 200s
    前台服务 10s
BroadCastQueue TimeOut: 有序广播未在规定时间内未处理完成
    前台广播 10s
    后台广播 60s
ContentProvider TimeOut
    启动动作  10s 内没有完成
    getResolver 20s 未获取成功(返回空,不会触发ANR)
Input Dispatching timeout
    5s 内未响应键盘输入、触摸屏幕等事件

Activity 的生命周期回调的阻塞并不在触发 ANR 的场景里面,所以并不会直接触发 ANR。只不过死循环阻塞了主线程,如果系统再有上述的四种事件发生,就无法在相应的时间内处理从而触发 ANR

Activity.onRestart调用场景

  1. 按下home键之后,然后切换回来,会调用onRestart()
  2. 从本Activity跳转到另一个Activity之后,按back键返回原来Activity,会调用onRestart()
  3. 从本Activity切换到其他的应用,然后再从其他应用切换回来,会调用onRestart()

Activity任务栈

LaunchMode应用场景
standard本应用内普通界面(很少自身跳转自身)
singleTop覆盖页面-逻辑不可控时使用-防止需要多次back:推送通知栏
singleTask应用主页、在线教室
singleInstance独立页面:来电显示、闹铃提醒(防止回退到自身)

注意:A -> B -> C -> D -> A -> B,A(Standard)和B(SingleTask)在一个任务栈,C(SingleTask)和D(SingleTask)在一个任务栈,返回时的顺序是B -> A -> A -> D -> C,需要考虑任务栈跳转的情况,优先清退当前任务栈

控制Activity栈行为的标志(自己测试不好用):allowTaskReparenting、finishOnTaskLaunch、clearTaskOnLaunch、alwaysRetainTaskState

参考文档

developer.android.com/guide/compo…

developer.android.com/guide/topic…

blog.csdn.net/hfy8971613/…