Activity启动流程分析
这道题想考察什么
考核activity 的启动过程,以及启动过程中各大类的关系
考生应该如何回答
Activity的启动过程一般有两种情况:第一种,activity所在的进程没有创建,那么这个过程就会涉及到App进程的创建,我们可以在《Android app进程是怎么启动的》的章节去得到详细说明,在这里就不赘述了;第二种,App进程存在,那么对应的Activity启动流程将是下面分析的重点。
下文会分析整个activity 启动的流程,同时分析一下它的生命周期的切换过程,最后再分析一下管理activity的几个类的基本情况。
1.Activity启动流程
平时我们开发的应用都是展示在Android系统桌面上,这个系统桌面其实也是一个Android应用,它叫Launcher。所以本文通过源码层面从Launcher调用ATMS,ATMS再通过AMS发送socket请求给zygote,由zygote fork出app进程,然后再通过反射调用ActivityThread 的main函数,开始运行app进程的代码。在ActivityThread main函数中,会执行AMS的 attachApplication方法,将Application的binder赋值给AMS,然后再由AMS通过这个IBinder去调用ApplicationThread的bindApplication函数执行application的生命周期,紧接着AMS再直线ATMS的attachApplication方法,进而启动Activity并执行Activity的相关生命周期。
下文我们将重点对Activity启动流程进行分析。
1.1 Launcher 调用Activity的过程
在这个阶段,Launcher只是一个app,当用户点击Launcher上app icon的时候就会执行Launcher中的代码,在这个流程里面,Launcher主要会通过Instrumentation类跨进程调用ATMS(android 10之前是AMS)的代码去启动Activity,具体的其他细节不是我们关注的重点,有感兴趣的同学可以自行查看源码进行了解。我们将分析的重点放到ATMS启动Activity的流程里面来。
图 29-1
从上图29-1,流程图可以看到,ActivityTaskManagerService是通过ActivityStarter来启动Activity,为什么存在ActivityStarter类呢?
1.1.1 ActivityStarter类的说明
ActivityStarter它是一个用于解释如何启动一个Activity的控制器,用来配置actiivty的各种熟悉并加载启动 Activity 的类,此类记录所有逻辑,用于确定如何将意图和标志转换为Activity以及关联的任务和堆栈。
在ActivityStarter中包含了一个静态内部类Request,这个类或许非常恰当的说明ActivityStarter的作用。它的部分代码如下:
static class Request {
...
IApplicationThread caller;
Intent intent;
NeededUriGrants intentGrants;
// A copy of the original requested intent, in case for ephemeral app launch.
Intent ephemeralIntent;
String resolvedType;
ActivityInfo activityInfo;
ResolveInfo resolveInfo;
IVoiceInteractionSession voiceSession;
IVoiceInteractor voiceInteractor;
IBinder resultTo;
String resultWho;
int requestCode;
int callingPid = DEFAULT_CALLING_PID;
int callingUid = DEFAULT_CALLING_UID;
String callingPackage;
@Nullable String callingFeatureId;
int realCallingPid = DEFAULT_REAL_CALLING_PID;
int realCallingUid = DEFAULT_REAL_CALLING_UID;
int startFlags;
SafeActivityOptions activityOptions;
boolean ignoreTargetSecurity;
boolean componentSpecified;
boolean avoidMoveToFront;
ActivityRecord[] outActivity;
Task inTask;
String reason;
ProfilerInfo profilerInfo;
Configuration globalConfig;
int userId;
WaitResult waitResult;
int filterCallingUid;
PendingIntentRecord originatingPendingIntent;
boolean allowBackgroundActivityStart;
...
}
上面的代码大家不能发现,这个类里面有非常多的参数,而这些参数就包含了启动activity的相关信息和被启动Activity的相关信息。我们不难知道,在启动activity之前把所有信息都准备全,这个工作就需要交给ActivityStarter类来做。另外,ActivityA启动ActivityB时,代码是这样的:startActivity(new Intent(ActivityA.this,ActivityB.class)),参数信息只有三个Intent,context和ActivityB.class,这些信息就会在ActivtyStarter类中被封装成为一个request,有了这些信息,才能去进行启动的下一步工作。
我们一起来看一下图29-1中的step 4 executeRequest的代码:
private int executeRequest(Request request) {
ActivityInfo aInfo = request.activityInfo;
ResolveInfo rInfo = request.resolveInfo;
String resultWho = request.resultWho;
Task inTask = request.inTask;
ActivityRecord sourceRecord = null;//code 1
ActivityRecord resultRecord = null;//code 2
if (resultTo != null) {
sourceRecord = mRootWindowContainer.isInAnyStack(resultTo); //code 3
......
if (sourceRecord != null) {
if (requestCode >= 0 && !sourceRecord.finishing) {
resultRecord = sourceRecord;
}
}
}
......
//code 4
final ActivityRecord r = new ActivityRecord(mService,callerApp, callingPid,
callingUid, callingPackage, callingFeatureId, intent, resolvedType,
aInfo,mService.getGlobalConfiguration(), resultRecord, resultWho,
requestCode,request.componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
//code 5
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
inTask,restrictedBgActivity, intentGrants);
}
1)上面代码中code 1 &code 2 定义了两个ActivityRecord;
2)code3处初始化sourceRecord,这个sourceRecord,就是构建了当前启动Activity的activity在AMS中的ActivtyRecord。比如ActivityA启动ActivityB,那么这个ActivityRecord就是ActivityA 在AMS中的存在形式。当然这也就是说要在启动新Activity之前要知道sourceReord是谁。
3)code4 new了一个ActivityRecord,它就是要被启动的Activity。
4)code5 调了startActivityUnchecked()方法,执行下一步的生命周期流程的调度。
1.1.2 ActivityStartController类
这个类相对较简单,看名字知道它是一个ActivityStart的控制器,这个类主要是接收Activity启动的各种请求,并将这些请求封装成为一个可以被ActivityStarter处理的活动。所以,ActivityStarter对象的产生,是由ActivityStartController提供的。同时,它还会负责处理围绕活动启动流程开始的环节的逻辑,如图29-1中的第5步,当app中有一系列的activity处于pending需要启动的时候,这个时候就会调用doPendingActivityLaunches方法,处理所有的pending的activity。
void doPendingActivityLaunches(boolean doResume) {
//循环获取所有的pending状态的Activity,并执行启动逻辑
while (!mPendingActivityLaunches.isEmpty()) {
final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
final ActivityStarter starter = obtainStarter(null /* intent */,
"pendingActivityLaunch");
try {
starter.startResolvedActivity(pal.r, pal.sourceRecord, null, null,
pal.startFlags, resume, pal.r.pendingOptions, null, pal.intentGrants);
} catch (Exception e) {
Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
pal.sendErrorResult(e.getMessage());
}
}
}
通过上面的代码,大家不难发现在图29-1中的第5步,所走的代码,其实就是将所有要启动而没有启动的Activity们进行统一的启动管理,只是真正启动的过程仍旧交由AcitivityStarter的startResolvedActivity去完成。
1.1.3 启动期间的黑白屏现象
在app启动的时候,在AcitivityStarter启动activity的时候会有一个特殊的过程,这个过程就是启动一个黑白屏,用于提醒用户,正在启动新的app。那么这个启动黑白屏的过程是怎样的的呢?
我们一起来看一下图29-1中的第8步的代码startActivityInner。
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
//初始化配置,mStartActivity、mLaunchMode等
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
// 计算要启动的Activity的task标志,也就是计算启动模式
computeLaunchingTaskFlags();
computeSourceStack();
//将mLaunchFlags设置给Intent,也就是设置启动模式
mIntent.setFlags(mLaunchFlags);
final Task reusedTask = getReusableTask();
......
// Compute if there is an existing task that should be used for.
final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
final boolean newTask = targetTask == null;
mTargetTask = targetTask;
computeLaunchParams(r, sourceRecord, targetTask);
...
// code1
// 创建启动黑白屏window
mTargetStack.startActivityLocked(mStartActivity,
topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask,
mKeepCurTransition, mOptions);
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
mTargetStack.ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS);
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
} else {
if (mTargetStack.isTopActivityFocusable()
&& !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityInner");
}
//code2 将启动流程交给RootWindowContainer去执行,并通过
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
}
......
return START_SUCCESS;
}
函数一开始先初始化启动activity需要的配置,然后再基于配置参数计算出启动模式,并将启动模式设置给Intent作为后期备用的变量。接着会运行到code1,此时便是创建一个黑白屏。在分析黑白屏创建方式前,我们先分析一下黑白屏为什么在Activity进程创建之前会启动?
当用户点击Launcher界面app icon的时候,为了让点击者在第一时间能够感受到点击的响应,此时必须要有界面切换来证明变化的存在。在app启动流程中,如果在app进程创建后才显示这个黑白屏,那么Launcher界面将出现一个比较长的等待时间,这将会被用户错误的认知为点击没有及时响应。因此,在app进程还没有创建的时候,在启动activity的过程中,一旦设置了activity的启动模式就立刻创建一个黑白屏,用于衔接点击app icon到app真正显示这中间的时间间隙,这也是在activity启动过程中的一个巧妙设计。关于黑白屏的具体显示流程,感兴趣的朋友可以去阅读其他相关章节补充学习。
1.1.4 RootWindowContainer类的说明
Android10新增的类,当activity启动的时候,会将整个启动流程转交给RootWindowContainer去执行,为什么会这样去做了?我们接下来分析。
RootWindowContainer是窗口容器(WindowContainer)的根容器,管理了所有窗口容器,设备上所有的窗口(Window)、显示(Display)都是由它来管理的。resumeFocusedStacksTopActivities函数会恢复对应任务栈顶部的Activity。这个方法会检查一些可见性相关的属性,如果当前需要resume的activityStack 是可见的,这个时候才resume,而可见性是由RootWindowContainer中的窗口控制的。所以,每个activity都有自己的窗口,为了控制activity窗口的可见性,Activity的启动必须经过RootWindowContainer。
1.1.5 小结
从图29-1可以看出,Activity的启动会有一个相对漫长的前期准备阶段,这个阶段所做的事情如下:
1)ATMS发出启动activity的请求;
2)将启动Activity的动作所需要准备的参数全部封装成为ActivityStarter里面的参数,也就是说ActivityStarter存储了一个activity启动所需要的所有的参数;
3)由于可能存在一次启动多个Activity的状况,或者积累了多个activity需要启动的情况,所以此时需要将所有可以启动的activity进行启动,因此启动流程需要去走到ActivityStarterController里面进行处理;
4)当真正启动Activity的时候,如果是启动的application的launcher activity,那么我们需要先提供一个黑白屏,因为在用户点击启动application的时候,用户需要对启动App这个动作有感知,然而此时App启动可能比较缓慢没办法立刻显示,因此就需要先创建一个黑白屏。
5)由于启动activity会改变activity的窗口的可见性,而这个可见性的管理是由RootWindowContainer进行,因此在启动路上需要经过这个类来进行可见性控制的管理。
接下来,我们继续分析Activity的启动流程
1.2 Activity启动流程在AMS中的执行
图29-2
1.2.1 ActivityRecord,Task,ActivityStack,ActivityStackSupervisor类说明
我们要理解Activity启动流程,首先是要了解一些关键类的信息。
ActivityRecord:一个ActivityRecord对应着一个Activity,保存着一个Activity的所有信息;但是一个Activity可能会有多个ActivityRecord,因为Activity可能会被启动多次,主要是取决于Activity的启动模式。
Task:Android系统中的每个Activity都位于一个Task中。一个Task能够包括多个Activity,同一个Activity也可能有多个实例。 在AndroidManifest.xml中,我们能够通过 android:launchMode 来控制Activity在Task中的实例。Task管理的意义还在于近期任务列表以及Back栈。 当你通过多任务键(有些设备上是长按Home键。有些设备上是专门提供的多任务键)调出多任务时,事实上就是从ActivityManagerService获取了近期启动的Task列表。
ActivityStack:Task是它的父类,是一个管理类,管理着所有Activity
,内部维护了Activity
的所有状态、特殊状态的Actvity和Activity以及相关的列表数据。
ActivityStackSupervisor:ActivityStack
是由ActivityStackSupervisor
来进行管理,而这个是在ATMS的initialize
中被创建出来的。ATMS初始化的时候,会创建一个ActivityStackSupervisor对象用于统一管理一些事务:1)将显示层次结构相关的内容移动到RootWindowContainer中;2)将与activity生命周期相关的事务的处理转交给ActivityLifeCyler处理;3)处理点击物理按键Menu键后任务栈的处理。
注意:在Android 11版本中上面的类的划分已经和之前的版本进行了非常大的修改,所以职责也各不相同,编者注意到在Android12版本中,已经去掉了ActivityStack类和ActivityStackSupervisor类,替代他们的是Task类和ActivityTaskSupervisor类,感兴趣的读者可以拿源码进行阅读。
小结:
在AMS启动的时候,会创建一个ActivityStackSupervisor对象,ActivityStackSupervisor创建和管理Android系统中所有应用的ActivityStack,一个ActivityStack对应和包含一个应用中所有的栈。
有了以上对类的基本理解,我们就很容易理解图29-2的流程了。
一个app所有的Activity都会被ActivityStack进行管理,因此启动Activity自然也是在ActivityStack中进行,所以在完成启动流程的前9步准备工作后,自然就在第10步迈入了ActivityStack中。ActivityStack开始真正的启动Activity的时候,需要先执行12步,第12步会先让当前正在显示的Activity执行它的pause生命周期,然后再去执行13步:准备启动指定的Activity。
大家可以看一下ActivityStack中下面的核心代码
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
// 停止当前的Activity
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
// 停止当前的Activity
pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);//code1
}
...
if (next.attachedToProcess()){
...
} else {
...
//启动指定的Activity
mStackSupervisor.startSpecificActivity(next, true, true); //code2
}
return true;
}
通过上面的code1,此处代码是用于pause 当前activity的代码,code2 则是启动特定Activity的代码。
关于startPausingLocked() 方法去触发当前Activity执行pause生命周期的具体流程,我们就不做系统分析了,大致流程会和执行activity onCreate的流程一致,感兴趣的读者可以自行阅读源码。我们将重点放到Activity启动上面来,所以请大家看下面的ClientTransaction传递流程。
1.3 Activity启动中事件的跨进程通信
图 29-4
从Android 8之后,activity的启动流程就加入了触发器的机制,这个机制出现的目的是为了更加友好的管理activity的生命周期,但是,本人感觉它更让人费解了。不管怎样,我们一起分析一下它的流程和类的关系,用于帮助我们了解这个流程。
ClientLifecycleManager 是管理 Activity 生命周期的,在 ActivityTaskManagerService 里面提供 getLifecycleManager 来获取此对象,其中 mLifecycleManager 是在 ActivityTaskManagerService 的构造方法里面初始化的。
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
......
private final ClientLifecycleManager mLifecycleManager;
......
public ActivityTaskManagerService(Context context) {
mContext = context;
mFactoryTest = FactoryTest.getMode();
mSystemThread = ActivityThread.currentActivityThread();
mUiContext = mSystemThread.getSystemUiContext();
mLifecycleManager = new ClientLifecycleManager();//mLifecycleManager初始化
mInternal = new LocalService();
......
}
......
//获取mLifecycleManager对象
ClientLifecycleManager getLifecycleManager() {
return mLifecycleManager;
}
......
}
相关类功能说明:
ClientTransactionItem 对象,一个回调消息,client 端可以调用执行,实现了 BaseClientRequest 接口,在接口里面定义了3个方法:preExecute,execute,poseExecute。
ClientTransaction 是一个容器,持有一系列可以发送给 client 的消息(比如声明周期的状态),包括有 mActivityCallbacks 列表和一个目标状态 mLifecycleStateRequest。
TransactionExecutor 用来执行 ClientTransaction,以正确的顺序管理事务执行 execute(),定义在 ActivityThread 应用端。
ClientTransactionHandler是一个抽象类,定义了一系列生命周期处理Activity生命周期的接口,由ActivityThread实现。
另外,有一个类也在这里和大家一起介绍一下:
ActivityLifecycleItem 继承自 ClientTransctionItem,主要的子类有 ResumeActivityItem、PauseActivityItem、StopActivityItem、DestoryActivityItem。
ActivityThread 它管理应用程序进程中主线程中执行的调度和执行活动、广播以及活动管理器请求的其他操作。
小结
图29-4展示的代码执行流程可以知道,第15步,生命周期的执行是ActivityStackSupervisor这个activity栈的大管家拿着在ATMS中所创建的ClientLifecycleManager去执行生命周期的触发器。而生命周期的处理必须要经过生命周期事物存储的容器来分发,也就是第16步走ClientTransaction。然而Activity生命周期的执行到目前为止还是在SystemServer进程也就是在AMS所在的进程中,最终Activity的生命周期的执行还必须是在App进程中,所以就有了第17步,通过binder调用将生命周期的执行分发给Activity所在的进程去执行。当IApplicationThread 收到AMS所在进程发送过来的生命周期处理消息的时候,开始发送一个handler事件来处理这个生命周期,这就是第18步的执行。最后,app进程会去执行生命周期的触发器来处理ClientTransation事件。
请大家重点关注一个细节,也就是第17步,进程间完成了一次从systemServer进程到Activity所在的app进程进行切换的过程。
1.4 应用进程中生命周期的执行流程
生命周期的执行到目前这一步算是一个重要的分水岭,因为接下来的执行过程全部是在App进程中进行,接下来的执行流程我们可以看一下下面的流程图。
在执行启动流程中,我们先来看第14步ActivityStackSupervisor中的realStartActivityLocked函数一段核心代码:
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
......
// Create activity launch transaction.
// 创建 clientTransaction 对象
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
//code1
// 添加LaunchActivityItem
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, proc.getReportedProcState(),
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
//需要Rusume的话,设置ResumeActivityItem到clientTransaction中
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
//code 2
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// code3
// Schedule transaction.
// 获取生命周期管理类 ClientLifecycleManager,并执行事务
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
return true;
}
以上代码创建了一个clientTransaction对象,并设置了clientTransaction对象的各参数。从上面的代码code1,我们构建了一个LaunchActivityItem,并且将它添加到了clientTransaction的Callback列表中;然后在code2中往clientTransaction中设置了当前阶段最终想要执行的生命周期状态,也就是到生命周期的resume状态,所以再code2 代码处向clientTransation中设置了LifecycleStateRequest,也就是本次transaction希望执行的activity的生命周期的最终的状态,也就是添加了ResumeActivityItem,最终状态是activity的resume;最后在code3 把这个封装的clientTransaction 传递给了ClientLifecycleManager,这个clientTransaction对象被第17步的跨进程通信传给了app进程,所以接下来生命周期的执行就会按照AMS中构建的生命周期管理想法开始执行,也就是会按照图29-5的流程开始执行。
在Activity启动流程执行到TransactionExecutor中的excute的时候,此时的代码已经执行到了app进程里面了。我们一起来看一下第19步execute函数的执行流程,流程中我们只展示核心代码:
public void execute(ClientTransaction transaction) {
......
executeCallbacks(transaction); //code1
executeLifecycleState(transaction); //code2
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
在第19步,也就是在执行上面的excute函数的时候,会执行两个非常重要的代码:code1&code2,code1就是我们流程图中的第20步,而code2 就是我们流程图中的第24步。我们一起来分析一下这两个流程:
1.4.1 执行executeCallbacks函数
code1所引发的第20步,这个过程是执行在14步ActivityStackSupervisor中的realStartActivityLocked里面添加的Callback的这个阶段,我们通过上面代码的分析可以得到一个结论,这次从第20步执行到第23步,整个流程是围绕当前Activity的launch流程进行。当大家阅读第22步handleLaunchActivity源码的时候,不难发现,在代码执行中会执行Activity的创建以及attach的生命周期函数,然后再执行onCreate生命周期,具体的代码如下:
ActivityThread.java
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
......
WindowManagerGlobal.initialize(); //code1
final Activity a = performLaunchActivity(r, customIntent); //code2
......
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//创建一个activity
activity = mInstrumentation.newActivity( //code 3
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
//LoadedApk 构建 makeApplication
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
......
if (activity != null) {
......
// Activity resources must be initialized with the same loaders as the
// application context.
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(activity);
//code4
//会在这个方法中创建Activity的PhoneWindow,并绑定对应的WindowManager。
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
//code5
// 设置 mLifecycleState 为 ON_CREATE
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
mLastReportedWindowingMode.put(activity.getActivityToken(),
config.windowConfiguration.getWindowingMode());
}
// 设置 mLifecycleState 为 ON_CREATE
r.setState(ON_CREATE);
// updatePendingActivityConfiguration() reads from mActivities to update
// ActivityClientRecord which runs in a different thread. Protect modifications to
// mActivities to avoid race.
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
上面代码code1处是启动windowManagerGlobal,由于windowManagerGlobal是单例模式,所以,一般认为windowManagerGlobal的初始化就是在此时,其实就是为activity准备WindowManagerService。在code2处,将执行performLaunchActivity,大家仔细阅读performLaunchActivity的函数会不难发现 code3处创建了一个activity实例对象。然后执行到code4处,此处执行了activity的attach 生命周期,在这个生命周期里面,构建了activity的唯一的phoneWindow对象,并且并绑定对应的WindowManager方便后期使用。然后代码会执行到code5,在code5里面就是调用Activity的onCreate生命周期的过程,同时mLifecycleState被设置为ON_CREATE,这个状态在后面执行第26步的时候将会用到。
1.4.2 执行executeLifecycleState函数
上面主要介绍了 TransactionExecutor#execute执行executeCallbacks的过程,下面我们一起介绍一下执行executeLifecycleState的过程,也就是执行第24步到31步的过程。
private void executeLifecycleState(ClientTransaction transaction) {
//获取ActivityLifecycleItem,我们知道这里获取的是我们之前添加的ResumeActivityItem
//其值是由第14步ActivityStackSupervisor中的realStartActivityLocked函数
final ActivityLifecycleItem lifecycleItem =
transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
final IBinder token = transaction.getActivityToken();
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
+ lifecycleItem + " for activity: "
+ getShortActivityName(token, mTransactionHandler));
}
if (r == null) {
// Ignore requests for non-existent client records for now.
return;
}
// Cycle to the state right before the final requested state.
//code1 关键点,ResumeActivityItem的getTargetState 是 ON_RESUME
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */,
transaction);
// Execute the final transition with proper parameters.
//code2 执行 ResumeActivityItem 的 execute
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
从上面的代码,我们发现code1处有一个非常重要的函数cycleToPath(),其中的 lifecycleItem.getTargetState() 返回值是 ON_RESUME。
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
//这里在performLaunchActivity设置了LifecycleState为ON_CREATE,即:start是ON_CREATE,
final int start = r.getLifecycleState();
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Cycle activity: "
+ getShortActivityName(r.token, mTransactionHandler)
+ " from: " + getStateName(start) + " to: " + getStateName(finish)
+ " excludeLastState: " + excludeLastState);
}
//这里的 start 是 ON_CREATE,finish 是 ON_RESUME
//通过 mHelper 调用 getLifecyclePath 返回的 path 是 ON_START,下面会有解析
//这里是 Activity 执行 onStart 函数的关键所在
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
//执行path中的相关的生命周期函数
performLifecycleSequence(r, path, transaction);
}
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
//通过mHelper调用getLifecyclePath返回的path 是 ON_START
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Transitioning activity: "
+ getShortActivityName(r.token, mTransactionHandler)
+ " to state: " + getStateName(state));
}
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r.token, false /* show */,
0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
//TransactionExecutorHelper.java
//excludeLastState 为 true, start 为 ON_CREATE(1),finish 为 ON_RESUME(3)
public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
if (start == UNDEFINED || finish == UNDEFINED) {
throw new IllegalArgumentException("Can't resolve lifecycle path for undefined state");
}
if (start == ON_RESTART || finish == ON_RESTART) {
throw new IllegalArgumentException(
"Can't start or finish in intermittent RESTART state");
}
if (finish == PRE_ON_CREATE && start != finish) {
throw new IllegalArgumentException("Can only start in pre-onCreate state");
}
mLifecycleSequence.clear();
if (finish >= start) {//走到此分支
// just go there
for (int i = start + 1; i <= finish; i++) {
//把 ON_START 和 ON_RESUME 添加到 mLifecycleSequence 中
mLifecycleSequence.add(i);
}
} else { // finish < start, can't just cycle down
......
}
// Remove last transition in case we want to perform it with some specific params.
// 关键点:因为 excludeLastState 为 true,所以删除掉 ON_RESUME 状态
if (excludeLastState && mLifecycleSequence.size() != 0) {
mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
}
return mLifecycleSequence;
}
通过以上代码逻辑结构,大家不难发现,整个过程是基于activity 的lifecycle的初始状态以及目标状态来进行运算,找到中间需要响应的其他生命周期状态,也就是计算从ON_CREATE作为start的状态(在ActivityThread 中执行performLaunchActivity的过程中设置的),到以ON_RESUME作为生命周期结束状态,然后计算其中还需要经历的生命周期过程,也就是ON_START状态的过程。其实这也就是为什么activity生命周期被封装成为触发器Transaction的过程。
然后,我们再重新回到executeLifecycleState的执行,当这个函数执行完成cycleToPath函数之后(里面会触发ActivityThread的handleStartActivity去执行acitivty的onStart 生命周期)就会运行到code2部分的代码进行运行lifecycleItem.execute(mTransactionHandler, token, mPendingActions)。lifecycleItem在executeLifecycleState 中我们知道lifecycleItem的值是ResumeActivityItem,此时代码就会运行到ResumeActivityItem#execute(),也就是第29步。最后会调用ActivityThread的handleResumeActivity(),进而执行Activity的onResume生命周期。
1.4.3 小结
在本阶段,主要是在Application进程通过跨进程接收从AMS封装好的ClientTransaction对象,ClientTransaction对象里面封装了需要App进程执行Activity生命周期的所有的事件,然后在activity所在的进程中,按照触发器的触发逻辑,顺序的执行activity的 创建->attach->onCreate->onStart->onResume生命周期。
在AMS进程中的会通过ActivityStackSupervisor将activity启动相关的事件封装成为一个ClientTransaction对象,然后由ClientLifecycleManager通过ClientTransaction的函数将ClientTransaction对象以跨进程通信的方式传递给ApplicationThread。在完成了跨进程后,这个触发器所携带的命令就会在Application进程中得到触发。Application所在的进程会通过Handler来启动触发器TransactionExecutor的执行。TransactionExecutor会按照AMS中设置的逻辑,逐步去分发Activity的生命周期,直到整个触发器所携带的生命周期状态被执行完成为止,也就是onResume状态得到执行为止。
1.5 启动Activity的Activity onPause生命周期的运行
在Activity A 启动Activity B的时候,当Activity B启动流程执行到onResume生命周期之后,这个时候Activity A才会去执行它的onPause生命周期,这个逻辑是怎样的呢?大家看下面的代码。
ActivityThread.java
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
......
// 回调 onResume
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
......
final Activity a = r.activity;
......
if (r.window == null && !a.mFinished && willBeVisible) {
......
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
// 添加 decorView 到 WindowManager
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}
} else if (!willBeVisible) {
......
}
......
// 主线程空闲时会执行 Idler
Looper.myQueue().addIdleHandler(new Idler());
}
在代码最后有一句代码:Looper.myQueue().addIdleHandler(new Idler())。IdleHandler 不知道大家是否熟悉,它提供了一种机制,当主线程消息队列空闲时,会执行 IdleHandler 的回调方法,如果不懂这个逻辑的可以找一下其他handler章节的内容进行学习。messageQueue 中在正常的消息处理机制之后,额外对 IdleHandler 进行了处理。当从Messagequeue中调用next函数去取Message时,在本次取到的 Message 为空或者需要延时处理的时候,就会去执行 mIdleHandlers 数组中的 IdleHandler 对象。所以,不出意外的话(主线程很忙),当新的 Activity 完成页面绘制并显示之后,主线程就可以停下歇一歇,来执行 IdleHandler 了。再回来 handleResumeActivity() 中来,Looper.myQueue().addIdleHandler(new Idler()) ,这里的 Idler 是 IdleHandler 的一个具体实现类。
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
boolean stopProfiling = false;
if (mBoundApplication != null && mProfiler.profileFd != null
&& mProfiler.autoStopProfiler) {
stopProfiling = true;
}
if (a != null) {
mNewActivities = null;
IActivityTaskManager am = ActivityTaskManager.getService();
ActivityClientRecord prev;
do {
if (localLOGV) Slog.v(
TAG, "Reporting idle of " + a +
" finished=" +
(a.activity != null && a.activity.mFinished));
if (a.activity != null && !a.activity.mFinished) {
try {
// code1 调用 AMS.activityIdle()
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
if (stopProfiling) {
mProfiler.stopProfiling();
}
applyPendingProcessState();
return false;
}
}
上面的代码在code1处调用AMS 的activityIdle(),这个时候就顺利的将代码的执行转移到了AMS所在的进程中。
通过上图大家不难发现:上面的流程证明,我们activity的stop和destroy生命周期在此处执行。也就是说此时会执行启动activity之前的上一个activity的onStop生命周期,或者onDestroy生命周期。当然,如果我们详细的分析ActivityStackSupervisor(ASS)的代码,我们会不难发现一个细节,等待销毁的Activity被保存在了 ASS 的 mStoppingActivities 集合中,它是一个 ArrayList<ActivityRecord>。
1.5.1 小结
Activity 的 onStop/onDestroy 是依赖 IdleHandler 来回调的,正常情况下当主线程空闲时会调用。但是由于某些特殊场景下的问题,导致主线程迟迟无法空闲,onStop/onDestroy 也会迟迟得不到调用。但这并不意味着 Activity 永远得不到回收,系统提供了一个兜底机制,当 onResume 回调 10s 之后,如果仍然没有得到调用,会主动触发。
1.6 总结
Activity的启动交由ATMS触发处理,在Activity启动前需要先在ActivityStarter类中解读包括Activity的启动模式在内的各种参数信息。确定好启动信息后通过创建一个黑白屏的方式反馈给用户一个信息:我们正在响应启动app的过程中。然后将启动流程转交给ActivityStack处理,因为在ActivityStack中存储了一个Application的所有Activity,因此在此时应用的各Activity应该如何响应需要由ActivityStack来统一安排,在这个过程中就必然涉及到Activity的pause和需要启动的Activity的“realstart”。为了更好的管理Activity启动过程中的各生命周期,在ActivityStackSupervisor里面会将生命周期的事件封装成为一个ClientTransaction,并将这个ClientTransaction的对象通过跨进程的方式发送给App进程,然后由app进程的TransactionExecutor统一去触发执行,直到完成Activity的onResume生命周期为止,总流程如下图所示。