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的流程里面来。

【Android面试题】Android Framework核心面试题——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中的执行

【Android面试题】Android Framework核心面试题——Activity启动流程分析_android_02

图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以及相关的列表数据。

ActivityStackSupervisorActivityStack是由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启动中事件的跨进程通信

【Android面试题】Android Framework核心面试题——Activity启动流程分析_android_03

图 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进程中进行,接下来的执行流程我们可以看一下下面的流程图。

【Android面试题】Android Framework核心面试题——Activity启动流程分析_面试_04

在执行启动流程中,我们先来看第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所在的进程中。

【Android面试题】Android Framework核心面试题——Activity启动流程分析_启动模式_05

通过上图大家不难发现:上面的流程证明,我们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生命周期为止,总流程如下图所示。

【Android面试题】Android Framework核心面试题——Activity启动流程分析_android_06