背景
在唤端过程中有个有趣的现象。 同一个 activity Task
Activity A打开B接着打开C
- 打开B间隔一段时间打开C,按顺序正常走B和C的onCreate 和onResume
- 打开B和C的时间很接近 只会走C的 onCreate 和onResume, 按返回键走到B的onCreate和onResume
- 1的状态下在后台去打开B和C B和C均不走生命周期方法 ,回到前台走到C的onCreate 和onResume,按返回键走到B的onCreate和onResume
- 2的状态下 代码内finish A,然后在后台5s内去打开B和C ,C会被直接调起走C的 onCreate 和onResume。
分析
基于Android 13.0.0-r11源码调试分析
场景1
走正常的acitivity 启动流程 按顺序启动B和 启动C
场景2
相对于场景1 两个activity启动时间接近。 启动第二个activity C时 C加入了Task 但是没通过allPausedActivitiesComplete 所以没有走后续相关流程,resumeTopActivity时获取到Top的activity是C 所以走了C的生命周期 B就没有走了 等点击返回键时resumeTopActivity获取到了B又走了一遍B的生命周期。
final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete();
if (!allPausedComplete) {
ProtoLog.v(WM_DEBUG_STATES,
"resumeTopActivity: Skip resume: some activity pausing.");
return false;
}
场景3
应用在后台调用startActivity时 并不会去创建对应Activity, 在system_server进程会有是否允许后台进程启动activity的判断 shouldAbortBackgroundActivityStart ****如果不允许,把Activity加入相应task后 就不去走相应Acitivity的流程了,在这个例子中按顺序把B和C加入Task, 点击app icon后,home进程调用startActivity A resumeTopActivity后发现C在最上层就会先去走C的创建和生命周期流程,点击返回键后发现B在最上层就去走B的创建和生命周期流程
场景4
有几个关键字段
lastActivityLaunchTime:A Activity的Launch时间
lastActivityFinishTime: A Activity的finish时间
lastStopAppSwitchesTime:这个字段是全局的 任意 app 按home键都会更新这个时间
条件1:当前时间不超过lastActivityLaunchTime或者不超过lastActivityFinishTime时间的10s
条件2: lastActivityLaunchTime或lastActivityFinishTime之后没有更改lastStopAppSwitchesTime
满足上面两个条件 activity能够正常起来。
if (appSwitchState == APP_SWITCH_ALLOW) {
// Allow if any activity in the caller has either started or finished very recently, and
// it must be started or finished after last stop app switches time.
final long now = SystemClock.uptimeMillis();
if (now - lastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
|| now - lastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
// If activity is started and finished before stop app switch time, we should not
// let app to be able to start background activity even it's in grace period.
if (lastActivityLaunchTime > lastStopAppSwitchesTime
|| lastActivityFinishTime > lastStopAppSwitchesTime) {
if (DEBUG_ACTIVITY_STARTS) {
Slog.d(TAG, "[Process(" + pid
+ ")] Activity start allowed: within "
+ ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period");
}
return true;
}
if (DEBUG_ACTIVITY_STARTS) {
Slog.d(TAG, "[Process(" + pid + ")] Activity start within "
+ ACTIVITY_BG_START_GRACE_PERIOD_MS
+ "ms grace period but also within stop app switch window");
}
}
}
堆栈记录
System_server进程 startActivity调用堆栈
at com.android.server.wm.TaskFragment.schedulePauseActivity(TaskFragment.java:1665)
at com.android.server.wm.TaskFragment.startPausing(TaskFragment.java:1608)
at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1198)
at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5003)
at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4938)
at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2260)
at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1935)
at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1661)
at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1216)
at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:702)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1260)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1223)
at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1198)
at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5222)
at android.os.Binder.execTransactInternal(Binder.java:1280)
at android.os.Binder.execTransact(Binder.java:1244)
System_server进程 com.android.server.wm.Task addChild调用堆栈
at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:742)
at com.android.server.wm.TaskFragment.addChild(TaskFragment.java:1835)
at com.android.server.wm.Task.addChild(Task.java:1429)
at com.android.server.wm.ActivityStarter.addOrReparentStartingActivity(ActivityStarter.java:2927)
at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1866)
at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1661)
at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1216)
at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:702)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1260)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1223)
at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1198)
at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5222)
at android.os.Binder.execTransactInternal(Binder.java:1280)
at android.os.Binder.execTransact(Binder.java:1244)
System_server进程 activityPaused调用堆栈
at com.android.server.wm.ActivityTaskSupervisor.realStartActivityLocked(ActivityTaskSupervisor.java:924)
at com.android.server.wm.ActivityTaskSupervisor.startSpecificActivity(ActivityTaskSupervisor.java:1042)
at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1483)
at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5003)
at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4938)
at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2260)
at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2246)
at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1735)
at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:5992)
at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:178)
at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:574)
at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:124)
at android.os.Binder.execTransactInternal(Binder.java:1280)
at android.os.Binder.execTransact(Binder.java:1244)
总结
事实上调用startActivity后,还是需要很多个步骤才能去完成activity的创建以及生命周期流程的走完,平常开发时也需要注意一些细节,比如连续调用两个activity 可能是后面的activity更早创建,如果有些逻辑依赖了前一个activity就可能出现问题。