流程简述
activity生命周期
应用生命周期
-
activity启动:onCreate()->onStart()->onResume()
onCreate()方法是activity被创建时回调,是第一个被调用的方法,可以做一些初始化操作,比如setContentView,图片预加载等。
onStart()方法表明activity正在启动,已经对用户可见,但是还没有在前台显示,还不可以对其进行交互操作。
onResume()方法表明activity已经在前台可见,可对其进行交互操作。可以在这个方法中初始化资源,和onCreate()方法一样。 -
点击Home键返回主界面(Activity不可见):->onPause()->onStop()
onPause()方法:表明activity处于停止状态,即可见但不能被触摸的状态,与onResume()方法对应。
onStop()方法:一般在onPause()方法被调用之后调用,表明activity已经停止或者被完全覆盖,若是内存紧张activity会被回收。 -
再次回到activity时:onRestart()->onStart()->onResume()
onRestart():表明activity正在重新启动,正在由不可见变为可见状态,一般为在A的基础上打开B,然后又回到A,这是A会回调此方法。 -
退出activity时:onPause()->onStop()->onDestroy()
onDestroy():生命周期中的最后一个方法,可以做一些回收工作,或者资源释放。
2-3多个activity之间生命周期分析
- 活动A-Activity跳转活动B-Activity,最后返回A-Activity(B-Activity为普通的活动)
第一步打开A-Activity:A-onCreate —> A-onStart --> A-onResume
第二步跳转B-Activity(此时A不可见):–> A-onPause —> B-onCreate —> B-onStart --> B-onResume --> A-onStop
第三步返回A-Activity:–> B-onPause --> A-onRestart —> A-onStart --> A-onResume --> B-onStop --> B-onDestroy - 活动A-Activity跳转活动B-Activity,最后返回A-Activity(B-Activity为对话框式滑动)
第一步打开A-Activity:A-onCreate —> A-onStart --> A-onResume
第二步跳转B-Activity(此时A可见):–> A-onPause —> B-onCreate —> B-onStart --> B-onResume --> A-onStop不会调用
第三步返回A-Activity:–> B-onPause --> A-onResume --> B-onStop --> B-onDestroy - 小结
新Activity启动前,旧Activity的onPause先调用,新Activity再执行onCreate —> onStart --> onResume,这是为了防止跳转Activity时,屏幕上是黑屏,用户体验极差。
onPause中不能做重量级操作、耗时操作,使新的Activity尽快显示出来并切换到前台。
关键类
代码位置:frameworks/base/core/java/android/app/
Instrumentation:用于实现应用程序检测代码的基类。当在打开程序指令的时候运行,这个类将在任何应用程- 序代码之前实例化,可以监视系统与应用程序的所有交互。在AndroidManifest.xml文件的标记
Activity:应用的某个activity入口
ActivityThread:管理应用进程的主线程的执行,跑在应用侧进程中
代码位置:frameworks/base/core/java/android/app/servertransaction/
ClientLifecycleManager:该类能够组合多个client生命周期转换请求/回调,并将它们作为单个事务执行 scheduleTransaction(clientTransaction)
LaunchActivityItem:基于ClientLifecycleManager,用于代理传递给应用onCreate、onStart
ResumeActivityItem:基于ClientLifecycleManager,用于代理传递给应用onResumed
ClientTransaction:一种容器,它保存一系列消息(比如声明周期的状态),这些消息可以发送给client
TransactionExecutor:以正确的顺序管理事务执行
代码位置:frameworks/base/services/core/java/com/android/server/am/
ActivityManagerService:统筹管理着android的四大组件;统一调度各应用进程
ActivityTaskManagerService:Android R之后新引入,专门用来管理Activity的启动,调度等功能
代码位置:frameworks/base/services/core/java/com/android/server/wm/
ActivityStarter:专门用于处理activity新启动
ActivityStartController:基于工厂设计模式,ActivityStarter的应用启动器
ActivityTaskSupervisor:Task启动过程中的较多数控制逻辑在这个类中完成
Task:一些相关联的activity的集合,但activity之间不一定非得相关联。
ActivityRecord:实际的Activity,一般挂在Task节点下
RootWindowContainer:窗口容器的根容器,直接管理 DisplayContent
TaskDisplayArea:系统中所有应用任务的父节点,用于管理Task
节点添加堆栈
dump层级结构adb shell dumpsys activity containers
,看看应用在层级结构树上的显示。
#1 DefaultTaskDisplayArea type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]
#2 Task=733 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]
#0 ActivityRecord{ecd587b u0 com.example.mysystemdialog/.MainActivity} t733} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]
#0 f789ef com.example.mysystemdialog/com.example.mysystemdialog.MainActivity type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]
从层级结构上看,我们要添加一个应用ActivityRecord,会先在DefaultTaskDisplayArea上添加应用Task。另外,应用启动完成后启动窗口会消失,因此层级结构上并没有显示启动窗口,但其添加过程是存在的。
在DefaultTaskDisplayArea上添加Task
WindowContainer : DefaultTaskDisplayArea@174962344addChild index child = Task{17c31b9 #733 type=standard}
WindowContainer : java.lang.Exception
WindowContainer : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:762)
WindowContainer : at com.android.server.wm.TaskDisplayArea.addChildTask(TaskDisplayArea.java:321)
WindowContainer : at com.android.server.wm.TaskDisplayArea.addChild(TaskDisplayArea.java:307)
WindowContainer : at com.android.server.wm.Task$Builder.build(Task.java:6633)
WindowContainer : at com.android.server.wm.TaskDisplayArea.getOrCreateRootTask(TaskDisplayArea.java:933)
WindowContainer : at com.android.server.wm.TaskDisplayArea.getOrCreateRootTask(TaskDisplayArea.java:958)
WindowContainer : at com.android.server.wm.RootWindowContainer.getOrCreateRootTask(RootWindowContainer.java:2850)
WindowContainer : at com.android.server.wm.ActivityStarter.getOrCreateRootTask(ActivityStarter.java:3111)
WindowContainer : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1894)
WindowContainer : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1671)
WindowContainer : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1224)
WindowContainer : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:710)
WindowContainer : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1292)
WindowContainer : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1233)
WindowContainer : at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1208)
WindowContainer : at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:896)
WindowContainer : at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5323)
WindowContainer : at android.os.Binder.execTransactInternal(Binder.java:1280)
WindowContainer : at android.os.Binder.execTransact(Binder.java:1244)
在Task上添加应用ActivityRecord
WindowContainer : Task{17c31b9 #733 type=standard A=10116:com.example.mysystemdialog}addChild index child = ActivityRecord{ecd587b u0 com.example.mysystemdialog/.MainActivity}
WindowContainer : java.lang.Exception
WindowContainer : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:762)
WindowContainer : at com.android.server.wm.TaskFragment.addChild(TaskFragment.java:1984)
WindowContainer : at com.android.server.wm.Task.addChild(Task.java:1441)
WindowContainer : at com.android.server.wm.ActivityStarter.addOrReparentStartingActivity(ActivityStarter.java:3020)
WindowContainer : at com.android.server.wm.ActivityStarter.setNewTask(ActivityStarter.java:2970)
WindowContainer : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1900)
WindowContainer : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1671)
WindowContainer : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1224)
WindowContainer : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:710)
WindowContainer : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1292)
WindowContainer : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1233)
WindowContainer : at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1208)
WindowContainer : at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:896)
WindowContainer : at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5323)
WindowContainer : at android.os.Binder.execTransactInternal(Binder.java:1280)
WindowContainer : at android.os.Binder.execTransact(Binder.java:1244)
给应用添加启动窗口
WindowContainer : ActivityRecord{ecd587b u0 com.example.mysystemdialog/.MainActivity} t733}addChild comparator child = Window{9e879d u0 Splash Screen com.example.mysystemdialog}
WindowContainer : java.lang.Exception
WindowContainer : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:727)
WindowContainer : at com.android.server.wm.WindowToken.addWindow(WindowToken.java:300)
WindowContainer : at com.android.server.wm.ActivityRecord.addWindow(ActivityRecord.java:4286)
WindowContainer : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1777)
WindowContainer : at com.android.server.wm.Session.addToDisplayAsUser(Session.java:214)
WindowContainer : at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:642)
WindowContainer : at com.android.server.wm.Session.onTransact(Session.java:178)
WindowContainer : at android.os.Binder.execTransactInternal(Binder.java:1285)
WindowContainer : at android.os.Binder.execTransact(Binder.java:1244)
在ActivityRecord上应用的windowState
WindowContainer : ActivityRecord{ecd587b u0 com.example.mysystemdialog/.MainActivity} t733}addChild comparator child = Window{f789ef u0 com.example.mysystemdialog/com.example.mysystemdialog.MainActivity}
WindowContainer : java.lang.Exception
WindowContainer : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:727)
WindowContainer : at com.android.server.wm.WindowToken.addWindow(WindowToken.java:300)
WindowContainer : at com.android.server.wm.ActivityRecord.addWindow(ActivityRecord.java:4286)
WindowContainer : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1777)
WindowContainer : at com.android.server.wm.Session.addToDisplayAsUser(Session.java:214)
WindowContainer : at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:642)
WindowContainer : at com.android.server.wm.Session.onTransact(Session.java:178)
WindowContainer : at android.os.Binder.execTransactInternal(Binder.java:1280)
WindowContainer : at android.os.Binder.execTransact(Binder.java:1244)
总体流程堆栈
桌面侧启动应用
Instrumentation : execStartActivity
Instrumentation : java.lang.Exception
Instrumentation : at android.app.Instrumentation.execStartActivity(Instrumentation.java:1802)
Instrumentation : at android.app.Activity.startActivityForResult(Activity.java:5507)
Instrumentation : at com.android.launcher3.Launcher.startActivityForResult(Launcher.java:1743)
Instrumentation : at com.android.launcher3.uioverrides.QuickstepLauncher.startActivityForResult(QuickstepLauncher.java:664)
Instrumentation : at android.app.Activity.startActivity(Activity.java:5959)
Instrumentation : at com.android.launcher3.views.ActivityContext.startActivitySafely(ActivityContext.java:308)
Instrumentation : at com.android.launcher3.Launcher.startActivitySafely(Launcher.java:2115)
Instrumentation : at com.android.launcher3.uioverrides.QuickstepLauncher.startActivitySafely(QuickstepLauncher.java:305)
Instrumentation : at com.android.launcher3.touch.ItemClickHandler.startAppShortcutOrInfoActivity(ItemClickHandler.java:346)
Instrumentation : at com.android.launcher3.touch.ItemClickHandler.onClick(ItemClickHandler.java:98)
Instrumentation : at com.android.launcher3.touch.ItemClickHandler.$r8$lambda$c3IcSovkrXGdCZtXy0f_A5Sz5VA(Unknown Source:0)
Instrumentation : at com.android.launcher3.touch.ItemClickHandler$$ExternalSyntheticLambda4.onClick(Unknown Source:0)
Instrumentation : at com.android.launcher3.uioverrides.QuickstepLauncher.onItemClicked(QuickstepLauncher.java:344)
Instrumentation : at com.android.launcher3.uioverrides.QuickstepLauncher$$ExternalSyntheticLambda5.onClick(Unknown Source:2)
Instrumentation : at android.view.View.performClick(View.java:7506)
Instrumentation : at android.view.View.performClickInternal(View.java:7483)
Instrumentation : at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
Instrumentation : at android.view.View$PerformClick.run(View.java:29357)
Instrumentation : at android.os.Handler.handleCallback(Handler.java:942)
Instrumentation : at android.os.Handler.dispatchMessage(Handler.java:99)
Instrumentation : at android.os.Looper.loopOnce(Looper.java:201)
Instrumentation : at android.os.Looper.loop(Looper.java:288)
Instrumentation : at android.app.ActivityThread.main(ActivityThread.java:7884)
Instrumentation : at java.lang.reflect.Method.invoke(Native Method)
Instrumentation : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
Instrumentation : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
在Instrumentation.execStartActivity中,通过IActivityTaskManager.aidl跨进程通信,调用到ActivityTaskManagerService.startActivity方法。
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getOpPackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
异步调用暂停Launcher进程并启动应用进程
TaskFragment : at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1294)
TaskFragment : at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5021)
TaskFragment : at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4951)
TaskFragment : at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2264)
TaskFragment : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1971)
TaskFragment : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1671)
TaskFragment : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1224)
TaskFragment : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:710)
TaskFragment : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1292)
TaskFragment : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1233)
TaskFragment : at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1208)
TaskFragment : at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:896)
TaskFragment : at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5323)
TaskFragment : at android.os.Binder.execTransactInternal(Binder.java:1280)
TaskFragment : at android.os.Binder.execTransact(Binder.java:1244)
TaskFragment.resumeTopActivity中进行暂停Launcher进程和启动应用进程操作
暂停Launcher进程:
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
启动应用进程:
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
暂停Launcher进程
TaskFragment : schedulePauseActivity
TaskFragment : java.lang.Exception
TaskFragment : at com.android.server.wm.TaskFragment.schedulePauseActivity(TaskFragment.java:1766)
TaskFragment : at com.android.server.wm.TaskFragment.startPausing(TaskFragment.java:1710)
TaskFragment : at com.android.server.wm.TaskFragment.startPausing(TaskFragment.java:1618)
TaskFragment : at com.android.server.wm.TaskDisplayArea.lambda$pauseBackTasks$5(TaskDisplayArea.java:1288)
TaskFragment : at com.android.server.wm.TaskDisplayArea.$r8$lambda$m5XHJk9c1RGMj6XWeVM475WcQIg(Unknown Source:0)
TaskFragment : at com.android.server.wm.TaskDisplayArea$$ExternalSyntheticLambda9.accept(Unknown Source:6)
TaskFragment : at com.android.server.wm.TaskFragment.forAllLeafTaskFragments(TaskFragment.java:1954)
TaskFragment : at com.android.server.wm.TaskDisplayArea.lambda$pauseBackTasks$6(TaskDisplayArea.java:1285)
TaskFragment : at com.android.server.wm.TaskDisplayArea.$r8$lambda$Bbr_9JIpdvMngBiuBSXkHUu4nwk(Unknown Source:0)
TaskFragment : at com.android.server.wm.TaskDisplayArea$$ExternalSyntheticLambda6.accept(Unknown Source:8)
TaskFragment : at com.android.server.wm.Task.forAllLeafTasks(Task.java:3171)
TaskFragment : at com.android.server.wm.Task.forAllLeafTasks(Task.java:3159)
TaskFragment : at com.android.server.wm.WindowContainer.forAllLeafTasks(WindowContainer.java:2084)
TaskFragment : at com.android.server.wm.TaskDisplayArea.pauseBackTasks(TaskDisplayArea.java:1269)
TaskFragment : at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1294)
TaskFragment : at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5021)
TaskFragment : at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4951)
TaskFragment : at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2264)
TaskFragment : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1971)
TaskFragment : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1671)
TaskFragment : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1224)
TaskFragment : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:710)
TaskFragment : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1292)
TaskFragment : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1233)
TaskFragment : at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1208)
TaskFragment : at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:896)
TaskFragment : at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5323)
TaskFragment : at android.os.Binder.execTransactInternal(Binder.java:1280)
TaskFragment : at android.os.Binder.execTransact(Binder.java:1244)
TaskFragment.schedulePauseActivity通过scheduleTransaction调用PauseActivityItem执行暂停操作。
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately, autoEnteringPip));
在PauseActivityItem调用了execute方法
client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, mAutoEnteringPip,
pendingActions, "PAUSE_ACTIVITY_ITEM");
Activity : performPause
Activity : java.lang.Exception
Activity : at android.app.Activity.performPause(Activity.java:8513)
Activity : at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1619)
Activity : at android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:5061)
Activity : at android.app.ActivityThread.performPauseActivity(ActivityThread.java:5022)
Activity : at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:4974)
Activity : at android.app.servertransaction.PauseActivityItem.execute(PauseActivityItem.java:51)
Activity : at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
Activity : at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:179)
Activity : at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
Activity : at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2303)
Activity : at android.os.Handler.dispatchMessage(Handler.java:106)
Activity : at android.os.Looper.loopOnce(Looper.java:201)
Activity : at android.os.Looper.loop(Looper.java:288)
Activity : at android.app.ActivityThread.main(ActivityThread.java:7885)
Activity : at java.lang.reflect.Method.invoke(Native Method)
Activity : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
Activity : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
在PauseActivityItem调用了postExecute方法
ActivityClient.getInstance().activityPaused(token);
通过IActivityClientController.aidl跨进程通信,调用到ActivityClientController.activityPaused方法。
TaskFragment : completePause
TaskFragment : java.lang.Exception
TaskFragment : at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1790)
TaskFragment : at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:6198)
TaskFragment : at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:190)
TaskFragment : at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:609)
TaskFragment : at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:127)
TaskFragment : at android.os.Binder.execTransactInternal(Binder.java:1280)
TaskFragment : at android.os.Binder.execTransact(Binder.java:1244)
启动应用进程
ActivityTaskManagerService : startProcessAsync
ActivityTaskManagerService : java.lang.Exception
ActivityTaskManagerService : at com.android.server.wm.ActivityTaskManagerService.startProcessAsync(ActivityTaskManagerService.java:4859)
ActivityTaskManagerService : at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1316)
ActivityTaskManagerService : at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5021)
ActivityTaskManagerService : at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4951)
ActivityTaskManagerService : at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2264)
ActivityTaskManagerService : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1971)
ActivityTaskManagerService : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1671)
ActivityTaskManagerService : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1224)
ActivityTaskManagerService : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:710)
ActivityTaskManagerService : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1292)
ActivityTaskManagerService : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1233)
ActivityTaskManagerService : at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1208)
ActivityTaskManagerService : at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:896)
ActivityTaskManagerService : at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5324)
ActivityTaskManagerService : at android.os.Binder.execTransactInternal(Binder.java:1280)
ActivityTaskManagerService : at android.os.Binder.execTransact(Binder.java:1244)
ActivityTaskManagerService.startProcessAsync 方法用来创建新的进程。Zygote 进程收到请求后,fork 出新的进程并调用 ActivityThread.main 方法。
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
ActivityManagerInternal.startProcess 方法是请求启动应用进程的起点。PooledLambda.obtainMessage 获取一个 Message,并为其指定 Callback。
创建新进程
ActivityThread : attach
ActivityThread : java.lang.Exception
ActivityThread : at android.app.ActivityThread.attach(ActivityThread.java:7563)
ActivityThread : at android.app.ActivityThread.main(ActivityThread.java:7872)
ActivityThread : at java.lang.reflect.Method.invoke(Native Method)
ActivityThread : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
ActivityThread : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
在ActivityThread.attach方法中通过IActivityTaskManager.aidl跨进程通信,调用ActivityManagerService.attachApplication方法
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
之后调用到ActivityManagerService.attachApplicationLocked,在通过IApplicationThread.aidl跨进程通信调用ActivityThread.ApplicationThread.bindApplication方法,新的进程与应用绑定。
真正启动应用
ActivityTaskSupervisor : realStartActivityLocked
ActivityTaskSupervisor : java.lang.Exception
ActivityTaskSupervisor : at com.android.server.wm.ActivityTaskSupervisor.realStartActivityLocked(ActivityTaskSupervisor.java:981)
ActivityTaskSupervisor : at com.android.server.wm.RootWindowContainer$AttachApplicationHelper.test(RootWindowContainer.java:3614)
ActivityTaskSupervisor : at com.android.server.wm.RootWindowContainer$AttachApplicationHelper.test(RootWindowContainer.java:3562)
ActivityTaskSupervisor : at com.android.server.wm.ActivityRecord.forAllActivities(ActivityRecord.java:4585)
ActivityTaskSupervisor : at com.android.server.wm.WindowContainer.forAllActivities(WindowContainer.java:1736)
ActivityTaskSupervisor : at com.android.server.wm.WindowContainer.forAllActivities(WindowContainer.java:1730)
ActivityTaskSupervisor : at com.android.server.wm.RootWindowContainer$AttachApplicationHelper.accept(RootWindowContainer.java:3602)
ActivityTaskSupervisor : at com.android.server.wm.RootWindowContainer$AttachApplicationHelper.accept(RootWindowContainer.java:3562)
ActivityTaskSupervisor : at com.android.server.wm.Task.forAllRootTasks(Task.java:3183)
ActivityTaskSupervisor : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2119)
ActivityTaskSupervisor : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2119)
ActivityTaskSupervisor : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2119)
ActivityTaskSupervisor : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2119)
ActivityTaskSupervisor : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2119)
ActivityTaskSupervisor : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2119)
ActivityTaskSupervisor : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2112)
ActivityTaskSupervisor : at com.android.server.wm.RootWindowContainer$AttachApplicationHelper.process(RootWindowContainer.java:3579)
ActivityTaskSupervisor : at com.android.server.wm.RootWindowContainer.attachApplication(RootWindowContainer.java:1814)
ActivityTaskSupervisor : at com.android.server.wm.ActivityTaskManagerService$LocalService.attachApplication(ActivityTaskManagerService.java:6229)
ActivityTaskSupervisor : at com.android.server.am.ActivityManagerService.attachApplicationLocked(ActivityManagerService.java:4940)
ActivityTaskSupervisor : at com.android.server.am.ActivityManagerService.attachApplication(ActivityManagerService.java:5031)
ActivityTaskSupervisor : at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2339)
ActivityTaskSupervisor : at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2628)
ActivityTaskSupervisor : at android.os.Binder.execTransactInternal(Binder.java:1280)
ActivityTaskSupervisor : at android.os.Binder.execTransact(Binder.java:1244)
在realStartActivityLocked方法中调用minimalResumeActivityLocked方法,通知应用进入resume,修改应用状态为resume并更新
if (andResume && readyToResume()) {
// As part of the process of launching, ActivityThread also performs
// a resume.
rootTask.minimalResumeActivityLocked(r);
}
应用进入到onCreate
通过clientTransaction调用LaunchActivityItem使应用进入到onCreate流程
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
results, newIntents, r.takeOptions(), isTransitionForward,
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));
在LaunchActivityItem调用了execute方法
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Activity : performCreate
Activity : java.lang.Exception
Activity : at android.app.Activity.performCreate(Activity.java:8327)
Activity : at android.app.Activity.performCreate(Activity.java:8322)
Activity : at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1418)
Activity : at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3622)
Activity : at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3778)
Activity : at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
Activity : at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:138)
Activity : at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
Activity : at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2303)
Activity : at android.os.Handler.dispatchMessage(Handler.java:106)
Activity : at android.os.Looper.loopOnce(Looper.java:201)
Activity : at android.os.Looper.loop(Looper.java:288)
Activity : at android.app.ActivityThread.main(ActivityThread.java:7884)
Activity : at java.lang.reflect.Method.invoke(Native Method)
Activity : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
Activity : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
应用进入到onResume
通过clientTransaction调用ResumeActivityItem使应用进入到onResume流程
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward,
r.shouldSendCompatFakeFocus());
在ResumeActivityItem调用了execute方法
client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
mShouldSendCompatFakeFocus, "RESUME_ACTIVITY");
Activity : performResume
Activity : java.lang.Exception
Activity : at android.app.Activity.performResume(Activity.java:8461)
Activity : at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4760)
Activity : at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4803)
Activity : at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
Activity : at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
Activity : at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:179)
Activity : at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
Activity : at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2303)
Activity : at android.os.Handler.dispatchMessage(Handler.java:106)
Activity : at android.os.Looper.loopOnce(Looper.java:201)
Activity : at android.os.Looper.loop(Looper.java:288)
Activity : at android.app.ActivityThread.main(ActivityThread.java:7885)
Activity : at java.lang.reflect.Method.invoke(Native Method)
Activity : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
Activity : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
在ResumeActivityItem调用了postExecute方法
ActivityClient.getInstance().activityResumed(token, client.isHandleSplashScreenExit(token));
ActivityRecord : activityResumedLocked
ActivityRecord : java.lang.Exception
ActivityRecord : at com.android.server.wm.ActivityRecord.activityResumedLocked(ActivityRecord.java:6099)
ActivityRecord : at com.android.server.wm.ActivityClientController.activityResumed(ActivityClientController.java:160)
ActivityRecord : at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:587)
ActivityRecord : at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:127)
ActivityRecord : at android.os.Binder.execTransactInternal(Binder.java:1285)
ActivityRecord : at android.os.Binder.execTransact(Binder.java:1244)
总体流程图
代码流程
1.Launcher点击应用图标
从Launcher的startActivitySafely()方法开始,会调用到ActivityContext中的startActivity(),再调用到Context.startActivity()。
在ContextWrapper中实现了Context的startActivity()方法
frameworks/base/core/java/android/content/ContextWrapper.java
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
mBase.startActivity(intent, options);
}
mBase
为Context对象。
Activity继承ContextThemeWrapper,而ContextThemeWrapper继承ContextWrapper,在Activity中重写了ContextWrapper中startActivity()方法。
代码路径:frameworks/base/core/java/android/app/Activity.java
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
getAutofillClientController().onStartActivity(intent, mIntent);
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
最终调用startActivityForResult方法,传入-1表示不需要获取startActivity的结果
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
调用mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
方法,交由Instrumentation去处理
1.Instrumentation类主要是用来监控应用程序与系统交互
2.mMainThread、mInstrumentation、mToken都是在attach()被赋值。
3.代码中的mMainThread是ActivityThread可以理解为一个进程,在这就是Launcher的主进程。
4.mToken是IBinder对象,是Binder代理,是Android中IPC重要部分
5.通过mMainThread获取一个ApplicationThread的引用,这个引用就是用来实现进程间通信的,具体来说就是ATMS所在系统进程通知应用程序进程进行的一系列操作。
代码路径:frameworks/base/core/java/android/app/Instrumentation.java
@UnsupportedAppUsage
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
......
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getOpPackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
1.ActivityTaskManager.getService()
返回IActivityTaskManager
2.ActivityTaskManagerService的声明为ActivityTaskManagerService extends IActivityTaskManager.Stub
3.所以通过ActivityTaskManager.getService()
获取ActivityTaskManagerService服务代理Context.ACTIVITY_TASK_SERVICE
,使用Binder调用ActivityTaskManagerService的startActivity()方法,下一步由ActivityTaskManagerService内部startActivityAsUser()方法处理
2.进入ActivityTaskManagerService
通过binder机制,由launcher进程进入到ATMS。调用ActivityTaskManagerService中的startActivity()
代码路径:frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
@Override
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions, int userId) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
//检查包名与CallingUid是否一致
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
SdkSandboxManagerLocal.class);
if (sdkSandboxManagerLocal == null) {
throw new IllegalStateException("SdkSandboxManagerLocal not found when starting"
+ " an activity from an SDK sandbox uid.");
}
sdkSandboxManagerLocal.enforceAllowedToStartActivity(intent);
}
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();
}
这里我们主要看最后一句return
1.ActivityStartController通过getActivityStartController()方法获取
2.ActivityStartController.obtainStarter()返回的是ActivityStarter对象
3.然后设置数据,实际调用的都是ActivityStarter中的设置数据方法,数据会被存在其内部类Request的对象mRequest之中,最终调用ActivityStarter的execute()方法
代码路径:frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/**
* Resolve necessary information according the request parameters provided earlier, and execute
* the request which begin the journey of starting an activity.
* @return The starter result.
*/
int execute() {
try {
......
// Add checkpoint for this shutdown or reboot attempt, so we can record the original
// intent action and package name.
if (mRequest.intent != null) {
String intentAction = mRequest.intent.getAction();
String callingPackage = mRequest.callingPackage;
if (intentAction != null && callingPackage != null
&& (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
|| Intent.ACTION_SHUTDOWN.equals(intentAction)
|| Intent.ACTION_REBOOT.equals(intentAction))) {
ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
}
}
int res;
synchronized (mService.mGlobalLock) {
final boolean globalConfigWillChange = mRequest.globalConfig != null
&& mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
......
res = resolveToHeavyWeightSwitcherIfNeeded();
if (res != START_SUCCESS) {
return res;
}
res = executeRequest(mRequest);
......
} finally {
onExecutionComplete();
}
}
res = executeRequest(mRequest);
创建了应用第一个activity的ActivityRecord对象,调用startActivityUnchecked(),之后走到startActivityInner()
/**
* Executing activity start request and starts the journey of starting an activity. Here
* begins with performing several preliminary checks. The normally activity launch flow will
* go through {@link #startActivityUnchecked} to {@link #startActivityInner}.
*/
private int executeRequest(Request request) {
if (TextUtils.isEmpty(request.reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
}
mLastStartReason = request.reason;
mLastStartActivityTimeMs = System.currentTimeMillis();
mLastStartActivityRecord = null;
final IApplicationThread caller = request.caller;
Intent intent = request.intent;
NeededUriGrants intentGrants = request.intentGrants;
String resolvedType = request.resolvedType;
ActivityInfo aInfo = request.activityInfo;
ResolveInfo rInfo = request.resolveInfo;
final IVoiceInteractionSession voiceSession = request.voiceSession;
final IBinder resultTo = request.resultTo;
String resultWho = request.resultWho;
int requestCode = request.requestCode;
int callingPid = request.callingPid;
int callingUid = request.callingUid;
String callingPackage = request.callingPackage;
String callingFeatureId = request.callingFeatureId;
final int realCallingPid = request.realCallingPid;
final int realCallingUid = request.realCallingUid;
final int startFlags = request.startFlags;
final SafeActivityOptions options = request.activityOptions;
Task inTask = request.inTask;
TaskFragment inTaskFragment = request.inTaskFragment;
int err = ActivityManager.START_SUCCESS;
// Pull the optional Ephemeral Installer-only bundle out of the options early.
final Bundle verificationBundle =
options != null ? options.popAppVerificationBundle() : null;
......
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
mLastStartActivityRecord = r;
......
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
inTask, inTaskFragment, restrictedBgActivity, intentGrants);
if (request.outActivity != null) {
request.outActivity[0] = mLastStartActivityRecord;
}
return mLastStartActivityResult;
}
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,inTask, inTaskFragment, restrictedBgActivity, intentGrants);
调用startActivityUnchecked()方法
/**
* Start an activity while most of preliminary checks has been done and caller has been
* confirmed that holds necessary permissions to do so.
* Here also ensures that the starting activity is removed if the start wasn't successful.
*/
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
int result = START_CANCELED;
final Task startedActivityRootTask;
// Create a transition now to record the original intent of actions taken within
// startActivityInner. Otherwise, logic in startActivityInner could start a different
// transition based on a sub-action.
// Only do the create here (and defer requestStart) since startActivityInner might abort.
final TransitionController transitionController = r.mTransitionController;
Transition newTransition = (!transitionController.isCollecting()
&& transitionController.getTransitionPlayer() != null)
? transitionController.createTransition(TRANSIT_OPEN) : null;
RemoteTransition remoteTransition = r.takeRemoteTransition();
if (newTransition != null && remoteTransition != null) {
newTransition.setRemoteTransition(remoteTransition);
}
transitionController.collect(r);
try {
mService.deferWindowLayout();
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
intentGrants);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
startedActivityRootTask = handleStartResult(r, options, result, newTransition,
remoteTransition);
mService.continueWindowLayout();
}
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
}
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask,inTaskFragment, restrictedBgActivity,intentGrants);
调用startActivityInner()方法
/**
* Start an activity and determine if the activity should be adding to the top of an existing
* task or delivered new intent to an existing activity. Also manipulating the activity task
* onto requested or valid root-task/display.
*
* Note: This method should only be called from {@link #startActivityUnchecked}.
*/
// TODO(b/152429287): Make it easier to exercise code paths through startActivityInner
@VisibleForTesting
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
voiceSession, voiceInteractor, restrictedBgActivity);
computeLaunchingTaskFlags();
computeSourceRootTask();
......
if (mTargetRootTask == null) {
//找到目标Task
mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
mOptions);
}
......
final Task startedTask = mStartActivity.getTask();
if (newTask) {
EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId);
}
//此处打印wm_create_activity日志
mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask);
mStartActivity.getTaskFragment().clearLastPausedActivity();
mRootWindowContainer.startPowerModeLaunchIfNeeded(
false /* forceSend */, mStartActivity);
final boolean isTaskSwitch = startedTask != prevTopTask && !startedTask.isEmbedded();
//处理Task和Activity进栈操作
mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
mOptions, sourceRecord);
if (mDoResume) {
final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
if (!mTargetRootTask.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
// If the activity is not focusable, we can't resume it, but still would like to
// make sure it becomes visible as it starts (this will also trigger entry
// animation). An example of this are PIP activities.
// Also, we don't want to resume activities in a task that currently has an overlay
// as the starting activity just needs to be in the visible paused state until the
// over is removed.
// Passing {@code null} as the start parameter ensures all activities are made
// visible.
mTargetRootTask.ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mTargetRootTask.mDisplayContent.executeAppTransition();
} else {
// If the target root-task was not previously focusable (previous top running
// activity on that root-task was not visible) then any prior calls to move the
// root-task to the will not update the focused root-task. If starting the new
// activity now allows the task root-task to be focusable, then ensure that we
// now update the focused root-task accordingly.
if (mTargetRootTask.isTopActivityFocusable()
&& !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
mTargetRootTask.moveToFront("startActivityInner");
}
//启动栈顶的Activity
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
}
mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
......
return START_SUCCESS;
}
这个方法主要干了这几件事:
1.computeLaunchingTaskFlags();
computeLaunchingTaskFlags()方法计算启动Activity的Flag值
2.mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,mOptions, sourceRecord);
startActivityLocked()处理Task和Activity进栈操作
3.mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
resumeFocusedTasksTopActivities()获取栈顶activity并恢复,即将设置成resume状态
2.1 计算启动Activity的Flag值
computeLaunchingTaskFlags();
代码路径:frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private void computeLaunchingTaskFlags() {
......
//mInTask是Task类型,此处为null,代表Activity要加入的栈不存在,因此需要判断是否需要新Task
if (mInTask == null) {
//mSourceRecord是ActivityRecord类型,它是用来描述“初始Activity”
//“初始Activity”:比如,ActivityA启动到了ActivityB,ActivityA就是初始Activity
//当我们使用Context或者Application启动Activity时,此时mSourceRecord为null
if (mSourceRecord == null) {
// This activity is not being started from another... in this
// case we -always- start a new task.
if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
"Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
}
//初始Activity 如果是在singleInstance栈(LAUNCH_SINGLE_INSTANCE)中的Activity,就需要添加FLAG_ACTIVITY_NEW_TASK的标识
//因为singleInstance只允许保存一个Activity
} else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
// The original activity who is starting us is running as a single
// instance... this new activity it is starting must go on its
// own task.
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
//如果Launch Mode 设置了singleInstance(LAUNCH_SINGLE_INSTANCE) 和singleTask (LAUNCH_SINGLE_TASK)
//则也要创建一个新栈
} else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
// The activity being started is a single instance... it always
// gets launched into its own task.
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
}
}
}
2.2 处理Task和Activity进栈操作
mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,mOptions, sourceRecord);
startActivityLocked()方法会调用positionChildAtTop()方法尝试将Task和Activity入栈。如果是Activity是以new Task的模式启动或者Task堆栈中不存在该Task id,则Task会重新入栈,并且放在栈的顶部。
注:Task先入栈,之后才是Activity入栈,它们是包含关系
代码路径:frameworks/base/services/core/java/com/android/server/wm/Task.java
void startActivityLocked(ActivityRecord r, @Nullable Task topTask, boolean newTask,
boolean isTaskSwitch, ActivityOptions options, @Nullable ActivityRecord sourceRecord) {
final ActivityRecord pipCandidate = findEnterPipOnTaskSwitchCandidate(topTask);
Task rTask = r.getTask();
final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
final boolean isOrhasTask = rTask == this || hasChild(rTask);
// mLaunchTaskBehind tasks get placed at the back of the task stack.
if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) {
// Last activity in task had been removed or ActivityManagerService is reusing task.
// Insert or replace.
// Might not even be in.
positionChildAtTop(rTask);
}
......
}
到此,应用第一个Activity的ActivityRecord已经创建,并找到其Task,最后在Task中将ActivityRecord插入到合适的位置。
2.3 获取栈顶activity并恢复,即将设置成resume状态
mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
代码路径:frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
boolean deferPause) {
if (!mTaskSupervisor.readyToResume()) {
return false;
}
boolean result = false;
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) {
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
deferPause);
}
......
return result;
}
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,deferPause);
调用resumeTopActivityUncheckedLocked
代码路径:frameworks/base/services/core/java/com/android/server/wm/Task.java
/**
* Ensure that the top activity in the root task is resumed.
*
* @param prev The previously resumed activity, for when in the process
* of pausing; can be null to call from elsewhere.
* @param options Activity options.
* @param deferPause When {@code true}, this will not pause back tasks.
*
* @return Returns true if something is being resumed, or false if
* nothing happened.
*
* NOTE: It is not safe to call this method directly as it can cause an activity in a
* non-focused root task to be resumed.
* Use {@link RootWindowContainer#resumeFocusedTasksTopActivities} to resume the
* right activity for the current system state.
*/
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean someActivityResumed = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
if (isLeafTask()) {
if (isFocusableAndVisible()) {
someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
}
} else {
int idx = mChildren.size() - 1;
while (idx >= 0) {
final Task child = (Task) getChildAt(idx--);
if (!child.isTopActivityFocusable()) {
continue;
}
if (child.getVisibility(null /* starting */)
!= TASK_FRAGMENT_VISIBILITY_VISIBLE) {
break;
}
someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options,
deferPause);
// Doing so in order to prevent IndexOOB since hierarchy might changes while
// resuming activities, for example dismissing split-screen while starting
// non-resizeable activity.
if (idx >= mChildren.size()) {
idx = mChildren.size() - 1;
}
}
}
// When resuming the top activity, it may be necessary to pause the top activity (for
// example, returning to the lock screen. We suppress the normal pause logic in
// {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
// end. We call the {@link ActivityTaskSupervisor#checkReadyForSleepLocked} again here
// to ensure any necessary pause logic occurs. In the case where the Activity will be
// shown regardless of the lock screen, the call to
// {@link ActivityTaskSupervisor#checkReadyForSleepLocked} is skipped.
final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return someActivityResumed;
}
someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
调用resumeTopActivityInnerLocked
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
// Not ready yet!
return false;
}
final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);
if (topActivity == null) {
// There are no activities left in this task, let's look somewhere else.
return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
}
final boolean[] resumed = new boolean[1];
final TaskFragment topFragment = topActivity.getTaskFragment();
resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
forAllLeafTaskFragments(f -> {
if (topFragment == f) {
return;
}
if (!f.canBeResumed(null /* starting */)) {
return;
}
resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
}, true);
return resumed[0];
}
resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
调用resumeTopActivity
代码路径:frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canResumeByCompat()) {
return false;
}
next.delayedResume = false;
final TaskDisplayArea taskDisplayArea = getDisplayArea();
// If the top activity is the resumed one, nothing to do.
if (mResumedActivity == next && next.isState(RESUMED)
&& taskDisplayArea.allResumedActivitiesComplete()) {
// Ensure the visibility gets updated before execute app transition.
taskDisplayArea.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
false /* preserveWindows */, true /* notifyClients */);
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
executeAppTransition(options);
// In a multi-resumed environment, like in a freeform device, the top
// activity can be resumed, but it might not be the focused app.
// Set focused app when top activity is resumed
if (taskDisplayArea.inMultiWindowMode() && taskDisplayArea.mDisplayContent != null
&& taskDisplayArea.mDisplayContent.mFocusedApp != next) {
taskDisplayArea.mDisplayContent.setFocusedApp(next);
}
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Top activity "
+ "resumed %s", next);
return false;
}
// If we are currently pausing an activity, then don't do anything until that is done.
final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete();
if (!allPausedComplete) {
ProtoLog.v(WM_DEBUG_STATES,
"resumeTopActivity: Skip resume: some activity pausing.");
return false;
}
// If we are sleeping, and there is no resumed activity, and the top activity is paused,
// well that is the state we want.
if (mLastPausedActivity == next && shouldSleepOrShutDownActivities()) {
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
executeAppTransition(options);
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Going to sleep and"
+ " all paused");
return false;
}
// Make sure that the user who owns this activity is started. If not,
// we will just leave it as is because someone should be bringing
// another user's activities to the top of the stack.
if (!mAtmService.mAmInternal.hasStartedUserState(next.mUserId)) {
Slog.w(TAG, "Skipping resume of top activity " + next
+ ": user " + next.mUserId + " is stopped");
return false;
}
// The activity may be waiting for stop, but that is no longer
// appropriate for it.
mTaskSupervisor.mStoppingActivities.remove(next);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
mTaskSupervisor.setLaunchSource(next.info.applicationInfo.uid);
ActivityRecord lastResumed = null;
final Task lastFocusedRootTask = taskDisplayArea.getLastFocusedRootTask();
if (lastFocusedRootTask != null && lastFocusedRootTask != getRootTaskFragment().asTask()) {
// So, why aren't we using prev here??? See the param comment on the method. prev
// doesn't represent the last resumed activity. However, the last focus stack does if
// it isn't null.
lastResumed = lastFocusedRootTask.getTopResumedActivity();
}
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
if (mResumedActivity != null) {
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Pausing %s", mResumedActivity);
pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */,
next, "resumeTopActivity");
}
if (pausing) {
ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivity: Skip resume: need to"
+ " start pausing");
// At this point we want to put the upcoming activity's process
// at the top of the LRU list, since we know we will be needing it
// very soon and it would be a waste to let it get killed if it
// happens to be sitting towards the end.
if (next.attachedToProcess()) {
next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
true /* activityChange */, false /* updateOomAdj */,
false /* addPendingTopUid */);
} else if (!next.isProcessRunning()) {
// Since the start-process is asynchronous, if we already know the process of next
// activity isn't running, we can start the process earlier to save the time to wait
// for the current activity to be paused.
final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
}
if (lastResumed != null) {
lastResumed.setWillCloseOrEnterPip(true);
}
return true;
} else if (mResumedActivity == next && next.isState(RESUMED)
&& taskDisplayArea.allResumedActivitiesComplete()) {
// It is possible for the activity to be resumed when we paused back stacks above if the
// next activity doesn't have to wait for pause to complete.
// So, nothing else to-do except:
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
executeAppTransition(options);
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Top activity resumed "
+ "(dontWaitForPause) %s", next);
return true;
}
// If the most recent activity was noHistory but was only stopped rather
// than stopped+finished because the device went to sleep, we need to make
// sure to finish it as we're making a new activity topmost.
if (shouldSleepActivities()) {
mTaskSupervisor.finishNoHistoryActivitiesIfNeeded(next);
}
if (prev != null && prev != next && next.nowVisible) {
// The next activity is already visible, so hide the previous
// activity's windows right now so we can show the new one ASAP.
// We only do this if the previous is finishing, which should mean
// it is on top of the one being resumed so hiding it quickly
// is good. Otherwise, we want to do the normal route of allowing
// the resumed activity to be shown so we can decide if the
// previous should actually be hidden depending on whether the
// new one is found to be full-screen or not.
if (prev.finishing) {
prev.setVisibility(false);
if (DEBUG_SWITCH) {
Slog.v(TAG_SWITCH, "Not waiting for visible to hide: " + prev
+ ", nowVisible=" + next.nowVisible);
}
} else {
if (DEBUG_SWITCH) {
Slog.v(TAG_SWITCH, "Previous already visible but still waiting to hide: " + prev
+ ", nowVisible=" + next.nowVisible);
}
}
}
// Launching this app's activity, make sure the app is no longer
// considered stopped.
try {
mTaskSupervisor.getActivityMetricsLogger()
.notifyBeforePackageUnstopped(next.packageName);
mAtmService.getPackageManager().setPackageStoppedState(
next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */
} catch (RemoteException e1) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ next.packageName + ": " + e);
}
// We are starting up the next activity, so tell the window manager
// that the previous one will be hidden soon. This way it can know
// to ignore it when computing the desired screen orientation.
boolean anim = true;
final DisplayContent dc = taskDisplayArea.mDisplayContent;
if (prev != null) {
if (prev.finishing) {
if (DEBUG_TRANSITION) {
Slog.v(TAG_TRANSITION, "Prepare close transition: prev=" + prev);
}
if (mTaskSupervisor.mNoAnimActivities.contains(prev)) {
anim = false;
dc.prepareAppTransition(TRANSIT_NONE);
} else {
dc.prepareAppTransition(TRANSIT_CLOSE);
}
prev.setVisibility(false);
} else {
if (DEBUG_TRANSITION) {
Slog.v(TAG_TRANSITION, "Prepare open transition: prev=" + prev);
}
if (mTaskSupervisor.mNoAnimActivities.contains(next)) {
anim = false;
dc.prepareAppTransition(TRANSIT_NONE);
} else {
dc.prepareAppTransition(TRANSIT_OPEN,
next.mLaunchTaskBehind ? TRANSIT_FLAG_OPEN_BEHIND : 0);
}
}
} else {
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
if (mTaskSupervisor.mNoAnimActivities.contains(next)) {
anim = false;
dc.prepareAppTransition(TRANSIT_NONE);
} else {
dc.prepareAppTransition(TRANSIT_OPEN);
}
}
if (anim) {
next.applyOptionsAnimation();
} else {
next.abortAndClearOptionsAnimation();
}
mTaskSupervisor.mNoAnimActivities.clear();
if (next.attachedToProcess()) {
if (DEBUG_SWITCH) {
Slog.v(TAG_SWITCH, "Resume running: " + next + " stopped=" + next.stopped
+ " visibleRequested=" + next.mVisibleRequested);
}
// If the previous activity is translucent, force a visibility update of
// the next activity, so that it's added to WM's opening app list, and
// transition animation can be set up properly.
// For example, pressing Home button with a translucent activity in focus.
// Launcher is already visible in this case. If we don't add it to opening
// apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
// TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
final boolean lastActivityTranslucent = inMultiWindowMode()
|| mLastPausedActivity != null && !mLastPausedActivity.occludesParent();
// This activity is now becoming visible.
if (!next.mVisibleRequested || next.stopped || lastActivityTranslucent) {
next.app.addToPendingTop();
next.setVisibility(true);
}
// schedule launch ticks to collect information about slow apps.
next.startLaunchTickingLocked();
ActivityRecord lastResumedActivity =
lastFocusedRootTask == null ? null
: lastFocusedRootTask.getTopResumedActivity();
final ActivityRecord.State lastState = next.getState();
mAtmService.updateCpuStats();
ProtoLog.v(WM_DEBUG_STATES, "Moving to RESUMED: %s (in existing)", next);
next.setState(RESUMED, "resumeTopActivity");
// Have the window manager re-evaluate the orientation of
// the screen based on the new activity order.
boolean notUpdated = true;
// Activity should also be visible if set mLaunchTaskBehind to true (see
// ActivityRecord#shouldBeVisibleIgnoringKeyguard()).
if (shouldBeVisible(next)) {
// We have special rotation behavior when here is some active activity that
// requests specific orientation or Keyguard is locked. Make sure all activity
// visibilities are set correctly as well as the transition is updated if needed
// to get the correct rotation behavior. Otherwise the following call to update
// the orientation may cause incorrect configurations delivered to client as a
// result of invisible window resize.
// TODO: Remove this once visibilities are set correctly immediately when
// starting an activity.
notUpdated = !mRootWindowContainer.ensureVisibilityAndConfig(next, getDisplayId(),
true /* markFrozenIfConfigChanged */, false /* deferResume */);
}
if (notUpdated) {
// The configuration update wasn't able to keep the existing
// instance of the activity, and instead started a new one.
// We should be all done, but let's just make sure our activity
// is still at the top and schedule another run if something
// weird happened.
ActivityRecord nextNext = topRunningActivity();
ProtoLog.i(WM_DEBUG_STATES, "Activity config changed during resume: "
+ "%s, new next: %s", next, nextNext);
if (nextNext != next) {
// Do over!
mTaskSupervisor.scheduleResumeTopActivities();
}
if (!next.mVisibleRequested || next.stopped) {
next.setVisibility(true);
}
next.completeResumeLocked();
return true;
}
try {
final ClientTransaction transaction =
ClientTransaction.obtain(next.app.getThread(), next.token);
// Deliver all pending results.
ArrayList<ResultInfo> a = next.results;
if (a != null) {
final int size = a.size();
if (!next.finishing && size > 0) {
if (DEBUG_RESULTS) {
Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a);
}
transaction.addCallback(ActivityResultItem.obtain(a));
}
}
if (next.newIntents != null) {
transaction.addCallback(
NewIntentItem.obtain(next.newIntents, true /* resume */));
}
// Well the app will no longer be stopped.
// Clear app token stopped state in window manager if needed.
next.notifyAppResumed(next.stopped);
EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next),
next.getTask().mTaskId, next.shortComponentName);
mAtmService.getAppWarningsLocked().onResumeActivity(next);
next.app.setPendingUiCleanAndForceProcessStateUpTo(mAtmService.mTopProcessState);
next.abortAndClearOptionsAnimation();
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
dc.isNextTransitionForward()));
mAtmService.getLifecycleManager().scheduleTransaction(transaction);
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Resumed %s", next);
} catch (Exception e) {
// Whoops, need to restart this activity!
ProtoLog.v(WM_DEBUG_STATES, "Resume failed; resetting state to %s: "
+ "%s", lastState, next);
next.setState(lastState, "resumeTopActivityInnerLocked");
// lastResumedActivity being non-null implies there is a lastStack present.
if (lastResumedActivity != null) {
lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
}
Slog.i(TAG, "Restarting because process died: " + next);
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else if (SHOW_APP_STARTING_PREVIEW && lastFocusedRootTask != null
&& lastFocusedRootTask.isTopRootTaskInDisplayArea()) {
next.showStartingWindow(false /* taskSwitch */);
}
mTaskSupervisor.startSpecificActivity(next, true, false);
return true;
}
// From this point on, if something goes wrong there is no way
// to recover the activity.
try {
next.completeResumeLocked();
} catch (Exception e) {
// If any exception gets thrown, toss away this
// activity and try the next one.
Slog.w(TAG, "Exception thrown during resume of " + next, e);
next.finishIfPossible("resume-exception", true /* oomAdj */);
return true;
}
} else {
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
next.showStartingWindow(false /* taskSwich */);
}
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Restarting %s", next);
mTaskSupervisor.startSpecificActivity(next, true, true);
}
return true;
}