文章目录
前言
一、热启动与冷启动选择
二、AMS 进程中执行的相关操作
三、通过 Binder 机制转到 ActivityThread 中执行的操作
总结
前言
上一篇博客 【Android 启动过程】Activity 启动源码分析 ( AMS -> ActivityThread、AMS 线程阶段 ) 分析的分支是启动 Activity 时 , 没有 Activity 对应的进程 , 需要先调用 Zygote 启动相应进程 , 然后再启动 Activity , 属于冷启动 ;
本篇博客补充下 " 热启动 " 的流程 ;
一、热启动与冷启动选择
在 ActivityStackSupervisor.startSpecificActivityLocked 方法中 , 判定要启动的 Activity 是否存在 , 决定要使用冷启动还是热启动 ;
如果启动时 , 发现已经存在 Activity 对应进程 , 那么执行下面的热启动方法 :
// 如果启动 Activity 时 , 发现进程存在 , 则直接启动 Activity , 热启动 realStartActivityLocked(r, app, andResume, checkConfig);
如果启动时 , 发现不存在 Activity 对应进程 , 那么执行下面的冷启动方法 :
// 如果启动 Activity 时 , 发现进程不存在 , 则启动进程, 然后再启动 Activity , 冷启动 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true);
ActivityStackSupervisor.startSpecificActivityLocked 方法代码 :
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener, RecentTasks.Callbacks { void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // 此活动的应用程序是否已在运行? ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); getLaunchTimeTracker().setLaunchTime(r); if (app != null && app.thread != null) { try { if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) { // 如果它是一个标记为在多个进程中运行的平台组件,请不要添加此项, // 因为它实际上是框架的一部分,因此在进程中作为单独的apk进行跟踪没有意义。 app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode, mService.mProcessStats); } // 如果启动 Activity 时 , 发现进程存在 , 则直接启动 Activity , 热启动 realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } // 如果抛出了死对象异常,则通过fall-through重新启动应用程序。 } // 如果启动 Activity 时 , 发现进程不存在 , 则启动进程, 然后再启动 Activity , 冷启动 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); } }
完整代码参考 /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java ;
二、AMS 进程中执行的相关操作
在 ActivityStackSupervisor.realStartActivityLocked 启动 Activity ;
最终调用 mService.getLifecycleManager().scheduleTransaction(clientTransaction) 方法 , 启动相关 Activity 启动事物 ;
ActivityStackSupervisor.realStartActivityLocked 相关代码如下 : public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener, RecentTasks.Callbacks { final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { if (!allPausedActivitiesComplete()) { // 当有活动暂停时,我们将跳过开始任何新活动,直到暂停完成。 // 注意:对于在暂停状态下启动的活动,我们也会这样做,因为它们将首先恢复,然后在客户端暂停。 if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, "realStartActivityLocked: Skipping start of r=" + r + " some activities pausing..."); return false; } final TaskRecord task = r.getTask(); final ActivityStack stack = task.getStack(); beginDeferResume(); try { r.startFreezingScreenLocked(app, 0); // 安排启动时间以收集有关慢速应用程序的信息。 r.startLaunchTickingLocked(); r.setProcess(app); if (getKeyguardController().isKeyguardLocked()) { r.notifyUnknownVisibilityLaunched(); } // 让窗口管理器根据新的活动顺序重新评估屏幕方向。 // 注意,这样做的结果是,它可以使用新的方向调用activity manager。 // 我们不关心这一点,因为活动当前未运行,所以我们只是重新启动它。 if (checkConfig) { // 推迟恢复,因为我们将很快启动新活动。 // 我们不希望在确保配置和尝试恢复重点堆栈的*活动的同时,重复启动同一记录。 ensureVisibilityAndConfig(r, r.getDisplayId(), false /* markFrozenIfConfigChanged */, true /* deferResume */); } if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */, true /* isTop */)) { // 仅当基于keyguard状态允许活动可见时,我们才将可见性设置为true。 // 这样可以避免在窗口管理器中将此设置为运动状态, // 而由于以后的调用而取消该设置,以确保将可见性设置回false的可见活动。 r.setVisibility(true); } try { // 下面的代码是启动 Activity 的核心代码 // Create activity launch transaction. final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken); 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.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, mService.isNextTransitionForward(), profilerInfo)); // 设置所需的最终状态。配置生命周期 final ActivityLifecycleItem lifecycleItem; if (andResume) { // 开启新的 Activity lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); } else { // 终止 Activity lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // 安排事务。 mService.getLifecycleManager().scheduleTransaction(clientTransaction); // 上面的代码是启动 Activity 的核心代码 } catch (RemoteException e) { } } finally { endDeferResume(); } return true; } }
完整代码参考 /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java ;