深入分析Android 9.0源代码——Activity启动流程

版权声明:本文为博主原创文章,转载请注明引用地址: https://blog.csdn.net/hongchi110/article/details/82890180

引言

点击此处查看《深入分析Android 9.0源代码》系列的组织结构和相关说明。


1 应用进程发起启动请求

本节的调用流程如下图所示:

(Context) Activity Instrumentation ActivityManager [1-2] startActivity() [3-4] startActivityForResult() [5] execStartActivity() [6] getService() (Context) Activity Instrumentation ActivityManager

注:
(1)由于编辑器渲染的时序图不支持“无触发对象消息”(在标准的时序图中,这种消息的起点为实心圆形,表示流程的开始),此处用“(Context)”虚指触发流程的起始对象。
(2)对于时序图中形如“A—[#num] method()—>B”的消息(连线为实线),它的含义是控制流由先前的对象A(直接)转移到对象B,然后调用对象B的编号为#num的method()方法。
(3)同名的重载方法调用会直接合并,其对应的方法编号也使用[#num1-#num2]的形式进行合并。


1.1 startActivity(ForResult)@Activity

Activity类的startActivity()对于Android开发者来说可谓是再熟悉不过了。作为应用进程启动Activity的入口,经过一系列方法重载调用后,startActivity()最终会调用startActivityForResult(),并且传入-1和null作为参数requestCodeoptions的值。

// #1 {root}/core/java/ android.app.Activity (L4872)
public void startActivity(Intent intent) {
    this.startActivity(intent, null); // 调用#2
}

// #2 {root}/core/java/ android.app.Activity (L4899)
public void startActivity(Intent intent, Bundle options) {
    if (options != null) 
        startActivityForResult(intent, -1, options);
    else
        startActivityForResult(intent, -1); // 调用#3
}

// #3 {root}/core/java/ android.app.Activity (L4543)
public void startActivityForResult(Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null); // 调用#4
}

// #4 {root}/core/java/ android.app.Activity (L4581)
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
    ...
}


1.2 startActivityForResult@Activity

startActivityForResult()委托Instrumentation对象的execStartActivity()执行Activity的启动流程,然后对其返回的启动结果进行处理。

// #4 {root}/core/java/ android.app.Activity (L4581)
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
    if (mParent == null) {
        ...
        Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
               this, mMainThread.getApplicationThread(), mToken, 
               this, intent, requestCode, options); // 调用#5
        if (ar != null)
            mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());
        if (requestCode >= 0) 
            mStartedActivity = true;
        ...
    }
    ...
}

【L-03】if (mParent == null) { … }
mParent是一个Activity类型的成员变量,它记录了当前Activity的父Activity。Activity之间的父子关系既可以通过在Manifest中设置android:parentActivityName属性来实现1,也可以由继承自ActivityGroup的类(例如TabActivity)来定义2(官方在API 13后已经弃用了ActivityGroup,并推荐使用Fragment作为替代3)。因此,通常情况下mParent的取值为null,从而后续代码进入if分支。

【L-05】Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(…);
mInstrumentation是一个Instrumentation类型的成员变量,简单来说可以理解为应用进程的“管家”。每个应用程序有且仅有一个Instrumentation对象,并且每个Activity内部都持有对它的引用4。此处通过调用Instrumentation对象的execStartActivity(),将后续的Activity启动流程委托给这位得力的“管家”来完成,然后从返回值ar中获取并处理对应的启动结果。

【L-09】mMainThread.sendActivityResult(…);
mMainThread是一个ActivityThread类型的成员变量,它就是“通常所说”的主线程(UI线程)。此处调用ActivityThread的sendActivityResult(),将包括execStartActivity()的返回值ar在内的启动结果(通过Handler)转发出去5。需要特别指出的是,ActivityThread并没有继承Thread类,严格来说它只是一个“运行在主线程的对象”。当一个Android应用进程被创建后,虚拟机会预先创建一个主线程6,然后在主线程中执行ActivityThread类的main方法(具体流程参见下文5.1节)。而真正意义上的“主线程Thread实例”虽然存在,但它的创建过程由虚拟机进行管理,所以相关的代码是不可见的7。综上所述,对于“主线程”这个概念比较严谨的描述是“ActivityThread运行的线程”8,而本文为了表述方便,仍会将ActivityThread直接称为主线程。

【L-12】mStartedActivity = true;
mStartedActivity是一个boolean类型的成员变量,当方法参数requestCode为非负值(即满足判断条件requestCode>=0)时,该变量被置为true,表明被启动的Activity关闭(调用finish())后会返回一个(通过事先调用setResult()设定的)结果给当前Activity9。在收到返回的结果之前,当前Activity将一直保持不可见的状态10


1.3 execStartActivity@Instrumentation

execStartActivity()获取系统服务ActivityManagerService(下文简称为AMS)的Binder代理对象,然后将Activity的启动请求通过IPC(进程间通信)发送给AMS进行处理。从这一时刻开始,应用进程的当前线程将会挂起,直到AMS进程(严格来说,AMS等众多Android系统关键服务都运行于system_server进程中,为了表述方便,本文直接将该进程称为“AMS进程”)执行完毕并返回。最终如果目标Activity无法正常启动,该方法会根据AMS返回的消息抛出对应的异常。

// #5 {root}/core/java/ android.app.Instrumentation (L1635)
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, 
        Activity target, Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    ...
    int result = ActivityManager.getService() // 调用#6
                                .startActivity(whoThread, who.getBasePackageName(), intent,
                                            intent.resolveTypeIfNeeded(who.getContentResolver()), 
                                            token, target != null ? target.mEmbeddedID : null, 
                                            requestCode, 0, null, options); // IPC调用#7
    checkStartActivityResult(result, intent);
    ...
}

【L-04】IApplicationThread whoThread = (IApplicationThread) contextThread;
该赋值语句中涉及类型为IBinder的参数contextThread,以及类型为IApplicationThread的局部变量whoThread。首先来分析contextThread,这个参数的值在上文1.2节分析过的caller方法startActivityForResult()中对应于mMainThread.getApplicationThread()。先前已提到mMainThread就是主线程,它的getApplicationThread()返回ApplicationThread类型的成员变量mAppThread。简单来说,mAppThread是一个Binder实体对象,它作为server端等待来自client端(即AMS)的请求然后进行处理11。接着再分析whoThread,它就是刚才提到过的ApplicationThread对象,由于它实现了AIDL接口IApplicationThread,所以此处可以进行类型转换。

【L-06】int result = ActivityManager.getService().startActivity(…);
先前提到,应用进程和AMS进程通过Binder机制进行通信,并且ApplicationThread对象在应用进程中作为server端,接收来自AMS的消息。那么反过来也能自然地想到,当应用进程作为client端主动向AMS发送请求时,同样也需要借助于类似的Binder代理对象,而它正是调用ActivityManager.getService()获得的IActivityManager类型的对象。随后调用的IActivityManager的startActivity(),实质上是通过AIDL调用AMS的startActivity()12

【L-11】checkStartActivityResult(result, intent);
checkStartActivityResult()的方法名就能看出,它对AMS调用startActivity()的返回值进行检查,如果由于缺少权限、类加载失败、Intent解析错误等原因导致Activity无法正常启动时,就会抛出对应的异常。例如,当Activity没有在Manifest中注册时,就会抛出开发者熟悉的ActivityNotFoundException异常,其中包含的异常信息为“Unable to find explicit activity class XXX; have you declared this activity in your AndroidManifest.xml?”。


1.4 getService@ActivityManager

上文1.3节中execStartActivity()获取的Binder代理对象是一个单例对象,它由应用进程中的ActivityManager类进行管理。

// #6 {root}/core/java/ android.app.ActivityManager (L4125)
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton = 
        new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
        final IActivityManager am = IActivityManager.Stub.asInterface(b);
        return am;
    }
};

【L-03】return IActivityManagerSingleton.get();
getService()返回静态常量IActivityManagerSingleton(注意这个变量命名不够规范,容易被误认为是一个类),它是一个IActivityManager单例对象,所有应用进程都通过这个唯一的Binder代理对象向AMS发送消息。此处的单例通过android.util包提供的Singleton工具类来实现,该类专门用于构建线程安全的懒加载单例对象13

【L-08】protected IActivityManager create() { … }
create()是Singleton类的抽象方法,它定义了单例对象的初始化流程。首次调用get()时会通过create()来创建单例对象,后续调用get()则会直接返回先前已创建的对象。

【L-09】final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
ServiceManager是Android系统服务的管理者,当一个服务在ServiceManager中注册后,客户进程就能通过调用getService()来查询和获取该服务的Binder代理对象14。此处传入的参数是Context.ACTIVITY_SERVICE,表明需要获取AMS的Binder代理对象。

【L-10】final IActivityManager am = IActivityManager.Stub.asInterface(b);
Binder对象在获取后并不能直接使用,还需要调用asInterface()将服务端的Binder对象转换为客户端所需的AIDL接口类型的对象。虽然Android提供的Binder机制可以实现进程间的通信,但是当服务端和客户端都在同一个进程时,IPC实为多此一举,此时直接通过本地方法调用即可进行通信15。因此,asInterface()在转换Binder对象时,会对服务端和客户端属于“相同进程”和“不同进程”这两种情况分别处理,从而返回一个对于客户端而言“最经济适用”的AIDL接口对象。


2 AMS处理启动请求

本节的调用流程如下图所示:

ActivityManager [AMS] ActivityStarter [ASS] ActivityStack [7] startActivity() [8-9] startActivityAsUser() [10] execute() [11] startActivityMayWait() [12-14] startActivity() [15] startActivityUnchecked() [16] resumeFocusedStackTopActivityLocked() [17] resumeTopActivityUncheckedLocked() [18] resumeTopActivityInnerLocked() ActivityManager [AMS] ActivityStarter [ASS] ActivityStack

注:由于编辑器限制对象文本的最大长度,时序图中对于名称较长的类使用方括号(“[]”)和缩写来表示。上图中[AMS]=ActivityManagerService, [ASS]=ActivityStackSupervisor。


2.1 startActivity(AsUser)@ActivityManagerService

作为AMS处理启动请求的入口方法,startActivity()经过两次方法重载调用,最终会调用startActivityAsUser()并额外传入两个与调用者权限检查相关的参数userIduserIdvalidateIncomingUser(直接赋值为true)。

// #7 {root}/services/core/java com.android.server.am.ActivityManagerService (L5079)
public final int startActivity(IApplicationThread caller, String callingPackage, 
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, 
        int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, 
            resultTo, resultWho, requestCode, startFlags, profilerInfo, 
            bOptions, UserHandle.getCallingUserId()); // 调用#8
}

// #8 {root}/services/core/java com.android.server.am.ActivityManagerService (L5088)
public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, 
        int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, 
            resultTo, resultWho, requestCode, startFlags, profilerInfo, 
            bOptions, userId, true); // 调用#9
}

// #9 {root}/services/core/java com.android.server.am.ActivityManagerService (L5096)
public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, 
        int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, 
        int userId, boolean validateIncomingUser) {
    ...
}


2.2 startActivityAsUser@ActivityManagerService

startActivityAsUser()对参数userId进行权限检查,然后将Activity启动请求转发给新创建的ActivityStarter对象。

// #9 {root}/services/core/java com.android.server.am.ActivityManagerService (L5096)
public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, 
        int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, 
        int userId, boolean validateIncomingUser) {
    ...
    userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser, 
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    return mActivityStartController.obtainStarter(intent, "startActivityAsUser").
            setCaller(caller).
            setCallingPackage(callingPackage).
            setResolvedType(resolvedType).
            setResultTo(resultTo).
            setResultWho(resultWho).
            setRequestCode(requestCode).
            setStartFlags(startFlags).
            setProfilerInfo(profilerInfo).
            setActivityOptions(bOptions).
            setMayWait(userId).
            execute(); // 调用#10
}

【L-09】userId = mActivityStartController.checkTargetUser(…);
mActivityStartController是一个ActivityStartController类型的成员变量,此处调用obtainStarter()创建ActivityStarter对象,然后调用一系列setX()方法配置ActivityStarter对象的参数,最后调用execute()让ActivityStarter对象接管Activity的启动请求。

【L-19】…setMayWait(userId)…
setMayWait()将ActivityStarter对象的成员变量mRequest.mayWait设置为true,该参数的作用将在下文2.3节中进行分析。


2.3 execute@ActivityStarter

execute()根据boolean变量mRequest.mayWait的值(在本文分析的执行流程中为true)调用对应的方法。

// #10 {root}/services/core/java com.android.server.am.ActivityStarter (L481)
int execute() {
    ...
    if (mRequest.mayWait) {
        return startActivityMayWait(mRequest.caller, mRequest.callingUid, mRequest.callingPackage, 
                mRequest.intent, mRequest.resolvedType, mRequest.voiceSession, 
                mRequest.voiceInteractor, mRequest.resultTo, mRequest.resultWho, 
                mRequest.requestCode, mRequest.startFlags, mRequest.profilerInfo, 
                mRequest.waitResult, mRequest.globalConfig, mRequest.activityOptions,
                mRequest.ignoreTargetSecurity, mRequest.userId, mRequest.inTask, mRequest.reason,
                mRequest.allowPendingRemoteAnimationRegistryLookup); // 调用#11
    }
    ...
}

【L-04】if (mRequest.mayWait) { … }
上文2.2节中caller方法startActivityAsUser()通过调用setMayWait()mRequest.mayWait设置为true,故此处会执行if分支。

【L-09】return startActivityMayWait(…, mRequest.waitResult, …);
上文2.2节中caller方法startActivityAsUser()没有调用过setWaitResult(),所以参数mRequest.waitResult的值为null,它的作用将在下文2.4节中进行分析。


2.4 startActivityMayWait@ActivityStarter

startActivityMayWait()的主要流程包括获取callingPid与callingUid、查询Activity对应的ActivityInfo16、调用(比入口方法有更多参数的)startActivity()重载方法执行后续Activity启动流程、判断线程是否需要wait。

// #11 {root}/services/core/java com.android.server.am.ActivityStarter (L945)
private int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage,
        Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, 
        IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, 
        int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration globalConfig, 
        SafeActivityOptions options, boolean ignoreTargetSecurity, int userId, TaskRecord inTask, 
        String reason, boolean allowPendingRemoteAnimationRegistryLookup) {
    ...
    final int realCallingPid = Binder.getCallingPid();
    final int realCallingUid = Binder.getCallingUid();
    int callingPid;
    if (callingUid >= 0) 
        callingPid = -1;
    else if (caller == null) {
        callingPid = realCallingPid;
        callingUid = realCallingUid;
    }
    else 
        callingPid = callingUid = -1;
    ...
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
            computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));
    ...
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    ...
    final ActivityRecord[] outRecord = new ActivityRecord[1];
    int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, 
            voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, 
            callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, 
            options, ignoreTargetSecurity, componentSpecified, outRecord, inTask, 
            reason, allowPendingRemoteAnimationRegistryLookup); // 调用#12
    ...
    if (outResult != null) { ... }
    ...
}

【L-21】ResolveInfo rInfo = mSupervisor.resolveIntent(…);
mSupervisor是一个ActivityStackSupervisor类型的成员变量,它是Android系统中Activity的栈管理器17,与Activity启动模式相关的android:launchMode属性和Intent的Flags参数正是由它负责处理。此处调用resolveIntent()返回的rInfo是一个ResolveInfo类型的局部变量,它实现了Parcable接口,用于维护解析Intent后得到的信息18。事实上ResolveInfo对象部分地对应于从Manifest的<intent>标签收集到的信息,例如应用的包名、类名、图标等。

【L-24】ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
当目标Activity通过隐式Intent来启动时,resolveActivity()负责解析传入的参数intentresolveTypeflag,从符合条件的Activity集合中选择一个“最匹配”的Activity作为目标Activity(当系统无法确定哪个Activity“最匹配”时会提示用户自行选择),然后返回用于描述其相关信息的ActivityInfo对象19

【L-26】final ActivityRecord[] outRecord = new ActivityRecord[1];
此处为目标Activity创建了一个长度为1的ActivityRecord数组outRecord,但是并没有立即为数组中的唯一元素赋值(具体的赋值过程将在下文2.5节中进行分析)。ActivityRecord对象用于描述Activity栈中的Activity实例,由于Activity可以被多次实例化(取决于Manifest中Activity的android:launchMode属性和Intent的Flags参数),从而同一个Activity可能会存在多个对应的ActivityRecord对象20

【L-33】if (outResult != null) { … }
outResult不为null时,if分支内部会调用service.wait()使线程进入wait状态,这正是方法名“startActivityMayWait”中“MayWait”一词的由来21。由于上文2.3节中caller方法execute()传入的参数mRequest.waitResult的值为null,也即不需要进入wait状态,所以此处省略了if分支中的相关代码。


2.5 startActivity@ActivityStarter

startActivity()经过多次重载调用,最终会调用startActivityUnchecked()。其中,第二个重载的startActivity()(方法编号#13)会执行一系列的检查,包括错误信息检查、权限检查、类加载检查等22。由于这部分检查流程比较复杂,此处略去相关的代码实现。

// #12 {root}/services/core/java com.android.server.am.ActivityStarter (L528)
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, 
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, 
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, 
        String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, 
        int realCallingPid, int realCallingUid, int startFlags, SafeActivityOptions options, 
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, 
        TaskRecord inTask, String reason, boolean allowPendingRemoteAnimationRegistryLookup) {
    ...
    mLastStartActivityRecord[0] = null;
    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
            aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, 
            callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
            options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
            inTask, allowPendingRemoteAnimationRegistryLookup); // 调用#13
    if (outActivity != null) 
        outActivity[0] = mLastStartActivityRecord[0];
    return getExternalResult(mLastStartActivityResult);
}

// #13 {root}/services/core/java com.android.server.am.ActivityStarter (L571)
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, 
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, 
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, 
        String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, 
        int realCallingPid, int realCallingUid, int startFlags, SafeActivityOptions options, 
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, 
        TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
    ...
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, 
            callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), 
            resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, 
            mSupervisor, checkedOptions, sourceRecord); 
    if (outActivity != null) 
        outActivity[0] = r;
    ...
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, 
            checkedOptions, inTask, outActivity); // 调用#14
}

// #14 {root}/services/core/java com.android.server.am.ActivityStarter (L1193)
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, 
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
    ...
    result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity); // 调用#15
}

【L-10】mLastStartActivityRecord[0] = null;
mLastStartActivityRecord是一个ActivityRecord[1]类型(长度为1的ActivityRecord数组)的成员变量,用于记录最近一次“试图”启动的Activity。它的初始值为null,并且作为参数传入后续调用的startActivity()

【L-14】mLastStartActivityResult = startActivity(…, mLastStartActivityRecord, …);
在调用第二个重载的startActivity()(方法编号#13)时,先前提到的mLastStartActivityRecord被作为参数传入。当方法返回时,其中的唯一元素将被设置为目标Activity对应的ActivityRecord。

【L-17】outActivity[0] = mLastStartActivityRecord[0]
此处将outActivity[0]赋值为mLastStartActivityRecord[0](即目标Activity对应的ActivityRecord)。上文2.4节中曾提到startActivityMayWait()创建了outRecord变量但没有立即赋值,实际上它的赋值过程就是在此处完成的。


2.6 startActivityUnchecked@ActivityStarter

startActivityUnchecked()的主要流程包括计算与启动模式有关的Flags、判断栈顶Activity是否可以复用、计算目标Activity所属的Task、将目标Activity置于Activity栈的栈顶、执行目标Activity的resume流程23。它的方法名中之所以带有“Unchecked”,是因为上文2.5节中caller方法startActivity()(方法编号#13)已经进行了相关检查,故此处不再需要执行额外的检查24

// #15 {root}/services/core/java com.android.server.am.ActivityStarter (L1220) 
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, 
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, 
        boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) {
    ...
    mIntent.setFlags(mLaunchFlags);
    ...
    final boolean dontStart = ...;
    if (dontStart) {
        ...
        deliverNewIntent(top);
        ...
        return START_DELIVERED_TO_TOP;
    }
    ...
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition, 
            mOptions);
    if (mDoResume) {
        ...
        if (!mTargetStack.isFocusable() || ...) {
            ...
        }
        else {
            if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) 
                mTargetStack.moveToFront("startActivityUnchecked");
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, 
                    mOptions); // 调用#16
        }
        ...
    }
    ...
}

【L-06】mIntent.setFlags(mLaunchFlags);
mLaunchFlags是一个int类型的成员变量,它的不同bit代表与Activity启动有关的Flags。由于某些Flags之间存在冲突,所以该变量保存的是对方法参数startFlags经过计算处理后最终获得的Flags值25

【L-08】final boolean dontStart = …;
dontStart是一个boolean类型的局部变量,该值为true表示目标Activity正好位于当前Activity栈的栈顶并且它的启动模式是诸如LAUNCH_SINGLE_TOP等允许栈顶复用的模式。在这种情况下,可以直接复用栈顶的Activity实例而不需要额外创建新的Activity。本文的执行流程假定栈顶Activity无法复用。

【L-11】deliverNewIntent(top);
当栈顶Activity可以直接复用时,deliverNewIntent()传入的参数top即为当前栈顶的ActivityRecord对象,该方法最终会调用对应Activity的onNewIntent()

【L-16】mTargetStack.startActivityLocked(…);
mTargetStack是一个ActivityStack类型的成员变量,它对应着目标Activity所属的Activity栈。当先前提到的局部变量dontStart为false(即无法复用栈顶Activity)时,结合android:launchMode属性和Intent的Flags参数可以计算出目标Activity所属的Activity栈。随后这个Activity栈将被切换到前台,并调用它的startActivityLocked()将目标Activity对应的ActivityRecord置于栈顶26

【L-18】if (mDoResume) { … }
mDoResume是一个boolean类型的成员变量,此处它的值取决于方法的参数doResume27,表示是否需要使目标Activity可见(在某些特殊的情况下可能需要延迟目标Activity的可见时间)28。由于上文2.5节startActivity()(方法编号#13)在重载调用startActivity()(方法编号#14)时传入的参数doResume为true,所以此处mDoResume的值也为true。需要特别注意的是,此处的“可见”对应“resume”一词,其含义是“将(ActivityRecord对应的)Activity设置为可见状态”,这个执行流程最终会回调Activity的onResume()。为了表述的准确性(对“resume”与“visible”进行区分),下文将直接使用“resume”一词来表达这个概念。

【L-20】if (!mTargetStack.isFocusable() || …)
mTargetStack.isFocusable()检查目标Activity所属的Activity栈是否能获得焦点。通常情况下,这个if语句的判断条件不会满足,从而后续代码进入else分支。

【L-25】mTargetStack.moveToFront(“startActivityUnchecked”);
mTargetStack能够获得焦点但目前尚未获得焦点时,调用它的moveToFront()会确保该Activity栈最终获得焦点29


2.7 resumeFocusedStackTopActivityLocked@ActivityStackSupervisor

resumeFocusedStackTopActivityLocked()将当前获得焦点的Activity栈的栈顶Activity设置为resume状态。此处“当前获得焦点的Activity栈”一定是目标Acitivity所属的Activity栈,这个契约条件由上文2.6节的caller方法startActivityUnchecked()来保证。

// #16 {root}/services/core/java com.android.server.am.ActivityStackSupervisor (L2214) 
boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target,
        ActivityOptions targetOptions) {
    ...
    if (targetStack != null && isFocusedStack(targetStack)) 
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); // 调用#17
    ...
}


2.8 resumeTopActivityUncheckedLocked@ActivityStack

resumeTopActivityUncheckedLocked()将Activity栈的栈顶Activity(即目标Activity)设置为resume状态。

// #17 {root}/services/core/java com.android.server.am.ActivityStack (L2282)
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mStackSupervisor.inResumeTopActivity) 
        return false;
    boolean result = false;
    try {
        mStackSupervisor.inResumeTopActivity = true;
        result = resumeTopActivityInnerLocked(prev, options); // 调用#18
        ...
    } 
    finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    return result;
}

【L-03】if (mStackSupervisor.inResumeTopActivity) { … }
mStackSupervisor.inResumeTopActivity是ActivityStackSupervisor对象的一个boolean类型的成员变量,每当resumeTopActivityUncheckedLocked()方法被调用/返回时它会被设置为true/false,以避免方法本身被重复地递归调用。


2.9 resumeTopActivityInnerLocked@ActivityStack

resumeTopActivityInnerLocked()首先pause当前正处于resume状态的Activity,然后启动目标Activity将其设置为resume状态。从这里也能看出,当旧的Activity进入pause状态后,新的Activity才能启动并最终进入resume状态(即旧的Activity的onPause()会确保在新的Activity的onResume()方法之前被调用)30。此外,如果目标Activity所属的进程尚未创建(例如在桌面点击图标启动应用的Main Activity,或者在Manifest中为目标Activity设置了android:process属性31),那么在启动Activity前还需要创建对应的进程。为了更加全面地展示Activity的启动流程,本文假定需要为目标Activity创建新的进程。

// #18 {root}/services/core/java com.android.server.am.ActivityStack (L2330)
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    ...
    final ActivityRecord next = topRunningActivityLocked(true);
    ...
    if (mResumedActivity != null) 
        pausing |= startPausingLocked(userLeaving, false, next, false); // 调用#19
    ...
    if (next.app != null && next.app.thread != null) {
        ...
        next.setState(RESUMED, "resumeTopActivityInnerLocked");
        ...
        mStackSupervisor.scheduleResumeTopActivities();
    } 
    else {
        ...
        mStackSupervisor.startSpecificActivityLocked(next, true, true); // 调用#38
    }
    ...
}

【L-04】final ActivityRecord next = topRunningActivityLocked(true);
topRunningActivityLocked()返回当前Activity栈中最接近栈顶的未处于finishing状态的ActivityRecord对象,并保存在局部变量next中。实际上,这个返回值就是需要启动的Activity。

【L-07】if (mResumedActivity != null) { … }
mResumedActivity是一个ActivityRecord类型的成员变量,它记录了当前正处于resume状态的Activity(下文简称为“ResumedActivity”)所对应的ActivityRecord对象。如果该值不为null,那么在启动目标Activity之前,需要先调用startPausingLocked()让ResumedActivity进入pause状态。需要特别注意的是,虽然next变量(即需要启动的Activity)作为第三个方法参数传入了startPausingLocked(),但是这个参数的含义(形参名称)是“resuming”,表明它并不是需要pause的Activity。实际上,startPausingLocked()内部依然通过成员变量mResumedActivity来获取需要pause的Activity,而此处传入的next参数仅用于合法性校验和记录日志。

【L-09】if (next.app != null && next.app.thread != null) { … }
在执行完mResumedActivity的pause流程后,接下来就可以正式启动目标Acitivity。next.appnext.app.thread分别是ProcessRecord和IApplicationThread类型的对象,当这两者不为null时表示目标Activity所属的进程已经存在,从而可以直接在对应的进程中执行Activity的resume流程。

【L-13】mStackSupervisor.scheduleResumeTopActivities();
当目标Activity所属的进程已经存在时,调用scheduleResumeTopActivities()将通过Handler发送RESUME_TOP_ACTIVITY_MSG消息,从而执行栈顶Activity(即目标Activity)的resume流程。

【L-17】mStackSupervisor.startSpecificActivityLocked(…);
当目标Activity所属的进程尚未创建时,调用startSpecificActivityLocked()将首先创建对应的进程(实际上是由Zygote进程fork一个新的进程32),然后继续在新创建的进程中执行后续的resume流程。


3 ResumedActivity执行pause流程

本节的调用流程如下图所示:

ActivityStack [CLM] ClientTransaction ApplicationThread [CTH] ActivityThread [19] startPausingLocked() [20-21] scheduleTransaction() [22] schedule() [23] scheduleTransaction() [24] scheduleTransaction() [25-28] sendMessage() ActivityStack [CLM] ClientTransaction ApplicationThread [CTH] ActivityThread


ActivityThread H TransactionExecutor PauseActivityItem Instrumentation Activity [29] handleMessage() [30] execute() [31] executeLifecycleState() [32] execute() [33] handlePauseActivity() [34] performPauseActivity() [35] performPauseActivityIfNeeded() [36] callActivityOnPause() [37] performPause() [-] onPause() ActivityThread H TransactionExecutor PauseActivityItem Instrumentation Activity

注:
(1)为了排版美观,此处将整个流程拆分为两个时序图进行绘制,分别展示pause请求的构造和发送流程、pause请求的处理流程。
(2)[CLM]=ClientLifecycleManager, [CTH]=ClientTransactionHandler。
(3)对于时序图中形如“A---[#num] method()--->B”的消息(连线为虚线),它的含义是控制流由先前的对象A(经过一些略去的中间流程后)最终转移到对象B,然后调用对象B的编号为#num的method()方法。
(4)onPause()对于理解执行流程具有重要意义,所以该方法被标注在流程图中。由于下文并没有具体对其进行分析,所以它的方法编号为“-”。


3.1 startPausingLocked@ActivityStack

上文2.9节中提到,当旧的Activity进入pause状态后,新的Activity才能启动并最终进入resume状态。此处startPausingLocked()作为ResumedActivity执行pause流程的入口方法,将流程相关的参数传递给ClientLifecycleManager对象。

// #19 {root}/services/core/java com.android.server.am.ActivityStack (L1415)
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, 
        boolean pauseImmediately) {
    ...
    ActivityRecord prev = mResumedActivity;
    ...
    prev.setState(PAUSING, "startPausingLocked");
    ...
    if (prev.app != null && prev.app.thread != null) {
        ...
        mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                    PauseActivityItem.obtain(prev.finishing, userLeaving, 
                            prev.configChangeFlags, pauseImmediately)); // 调用#20
        ...
    }
    ...
}

【L-05】ActivityRecord prev = mResumedActivity;
mResumedActivity这个成员变量在上文2.9节中曾经提到过,它记录了ResumedActivity所对应的ActivityRecord对象。

【L-09】if (prev.app != null && prev.app.thread != null) { … }
上文2.9节中曾经分析过类似的语句,此处的条件判断用于检测prev变量所对应的进程是否已经创建。通常情况下ResumedActivity对应的进程必然存在,所以后续代码进入if分支。

【L-11】mService.getLifecycleManager().scheduleTransaction(…);
mService是一个ActivityManagerService类型的成员变量,它的getLifecycleManager()返回一个ClientLifecycleManager对象。ClientLifecycleManager是Android 9.0新增的一个工具类33,该类定义了若干名称带有“Transaction”的方法,用于将来自客户端(即应用进程)的状态请求和回调方法合并为一个transcation执行。

【L-12】PauseActivityItem.obtain(…);
PauseActivityItem类封装了一个Activity的pause请求,它继承自ActivityLifecycleItem类,而ActivityLifecycleItem类又继承自ClientTransactionItem类。


3.2 scheduleTransaction@ClientLifecycleManager

ClientLifecycleManager对象通过重载调用scheduleTransaction()创建了一个封装pause流程的ClientTransaction对象,然后调用ClientTransaction对象的schedule()执行transcation。

// #20 {root}/services/core/java com.android.server.am.ClientLifecycleManager (L65)
void scheduleTransaction(IApplicationThread client, IBinder activityToken, 
        ActivityLifecycleItem stateRequest) throws RemoteException {
    final ClientTransaction clientTransaction = transactionWithState(client, activityToken, 
            stateRequest); 
    scheduleTransaction(clientTransaction); // 调用#21
}

// #21 {root}/services/core/java com.android.server.am.ClientLifecycleManager (L45)
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ...
    transaction.schedule(); // 调用#22
    ...
}

【L-04】final ClientTransaction clientTransaction = transactionWithState(…);
transactionWithState()创建封装pause流程的ClientTransaction对象,其中涉及两个重要的方法setLifecycleStateRequest()addCallback(),分别用于设置ClientTransaction的成员变量mLifecycleStateRequest(Activity的状态请求)和mActivityCallbacks(回调方法的集合)。此处的流程中仅调用了setLifecycleStateRequest()而没有调用addCallback(),所以mLifecycleStateRequest被设置为pause请求(即参数stateRequest,对应于上文3.1节中caller方法传入的PauseActivityItem对象),而mActivityCallbacks为空集合。下文3.8节在分析ClientTransaction对象最终的执行流程时,还会再次提到这两个重要的成员变量。


3.3 schedule@ClientTransaction

schedule()是一个IPC调用,所以后续的执行流程将切换到ResumedActivity所属的应用进程来完成。

// #22 {root}/core/java/ android.app.servertransaction.ClientTransaction (L128)
public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this); // IPC调用#23
}

【L-03】final IApplicationThread client = transaction.getClient();
mClient是一个IApplicationThread 类型的成员变量,它是transaction的目标应用进程的Binder代理对象。上文1.3节中曾经提到过,应用进程作为client端主动向AMS发送请求时,需要获取IActivityManager接口的Binder代理对象。类似地,此处AMS会反转角色作为客户端,通过IApplicationThread接口的Binder代理对象,主动通知应用进程执行Activity的pause流程。


3.4 scheduleTransaction@ApplicationThread

ApplicationThread类是ActivityThread类的一个内部类,它直接将transaction交给外部类ActivityThread的scheduleTransaction()进行处理。

// #23 {root}/core/java/ android.app.ActivityThread$ApplicationThread (L1539)
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction); // 调用#24
}

【L-03】ActivityThread.this.scheduleTransaction(transaction);
ApplicationThread类继承自IApplicationThread.Stub类,也就是AIDL接口IApplicationThread在server端(即应用进程)的实现类。同时,它也是ActivityThread类的内部类,所以通过ActivityThread.this可以获取隐式持有的外部类引用,然后由外部类ActivityThread调用scheduleTransaction()来处理transaction。


3.5 scheduleTransaction@ClientTransactionHandler

ActivityThread类继承自ClientTransactionHandler抽象类,所以上文3.4节中提到的scheduleTransaction()实际上是在这个抽象类中定义的。该方法首先对transaction进行预处理,然后将其封装为一个消息进行发送。

// #24 {root}/core/java/ android.app.servertransaction.ClientTransaction (L43)
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); // 调用#25
}

【L-04】sendMessage(…);
由于sendMessage()是一个抽象方法,所以后续调用的实际上是ActivityThread类中实现的sendMessage()


3.6 sendMessage@ActivityThread

ActivityThread类的sendMessage()经过四次重载调用,最终将消息发送给一个名称为mH的Handler进行处理。

// #25 {root}/core/java/ android.app.ActivityThread (L2756)
void sendMessage(int what, Object obj) {
    sendMessage(what, obj, 0, 0, false); // 调用#26
}

// #26 {root}/core/java/ android.app.ActivityThread (L2760)
private void sendMessage(int what, Object obj, int arg1) {
    sendMessage(what, obj, arg1, 0, false); // 调用#27
}

// #27 {root}/core/java/ android.app.ActivityThread (L2764)
private void sendMessage(int what, Object obj, int arg1, int arg2) {
    sendMessage(what, obj, arg1, arg2, false); // 调用#28
}

// #28 {root}/core/java/ android.app.ActivityThread (L2768)
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) 
        msg.setAsynchronous(true);
    mH.sendMessage(msg); // 最终调用#29
}

【L-25】mH.sendMessage(msg);
mH是一个H类型的成员变量,而H类也是ActivityThread的一个内部类。由于H类继承自Handler类,所以能自然地联想到它的职责是发送和处理消息。根据Android的消息处理机制,此处发送的消息最终将由mHhandleMessage()进行处理。


3.7 handleMessage@H

根据消息的what值的不同,H类的handleMessage()可以处理多达四十余种不同的消息。由于上文3.5节中caller方法scheduleTransaction()发送的消息的what值为ActivityThread.H.EXECUTE_TRANSACTION,所以此处只展示该消息的处理流程。

// #29 {root}/core/java/ android.app.ActivityThread$H (L1644)
public void handleMessage(Message msg) {
    switch (msg.what) {
        ...
        case EXECUTE_TRANSACTION:
            final ClientTransaction transaction = (ClientTransaction) msg.obj;
            mTransactionExecutor.execute(transaction); // 调用#30
            ...
            break;
        ...
    }
    ...
}

【L-07】mTransactionExecutor.execute(transaction);
mTransactionExecutor是一个TransactionExecutor类型的成员变量,它负责将transaction中包含的状态请求和(多个)回调方法以正确的顺序执行。


3.8 execute@TransactionExecutor

上文3.2节中提到,ClientTransaction对象有两个重要的成员变量mActivityCallbacksmLifecycleStateRequest,它们分别记录了回调方法和状态请求。由于mActivityCallbacks的实际类型是List<ClientTransactionItem>,所以execute()在执行transaction时将首先按照集合中的元素的顺序依次执行回调方法,然后再处理状态请求。

// #30 {root}/core/java/ android.app.servertransaction.TransactionExecutor (L64)
public void execute(ClientTransaction transaction) {
    ...
    executeCallbacks(transaction);
    executeLifecycleState(transaction); // 调用#31
    ...
}

【L-04】executeCallbacks(transaction);
上文3.2节中提到,transaction对象在创建过程中并没有添加回调方法,所以它的mActivityCallbacks成员变量为空34,也即此处的executeCallbacks()不需要执行任何回调方法。

【L-05】executeLifecycleState(transaction);
上文3.2节中提到,transaction对象在创建过程中将mLifecycleStateRequest成员变量设置为PauseActivityItem,所以此处executeLifecycleState()会处理对应的Activity的pause请求。


3.9 executeLifecycleState@TransactionExecutor

executeLifecycleState()获取transaction的状态请求ActivityLifecycleItem对象后,首先对其进行合法性检查,然后调用它的execute()执行对应的流程。

// #31 {root}/core/java/ android.app.servertransaction.TransactionExecutor (L125)
private void executeLifecycleState(ClientTransaction transaction) {
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    ...
    cycleToPath(r, lifecycleItem.getTargetState(), true);
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions); // 调用#32
}

【L-05】cycleToPath(…);
cycleToPath()检查Activity的当前状态能否直接切换到transaction请求的状态,如果其中存在某些中间状态,则需要先完成这些中间状态的切换。此处执行的是ResumedActivity从resume状态到pause状态的切换,由于这两个状态之间并不存在其它的状态,所以cycleToPath()实际上没有执行额外的操作35

【L-06】lifecycleItem.execute(…);
lifecycleItem是一个ActivityLifecycleItem类型的局部变量,此处它的实际类型是PauseActivityItem。由于抽象类ActivityLifecycleItem的execute()是一个抽象方法,所以此处调用的是子类PauseActivityItem实现的execute()


3.10 execute@PauseActivityItem

execute()获取PauseActivityItem的部分成员变量(即pause请求封装的参数),然后将它们作为参数传递给ActivityThread的handlePauseActivity()进行处理。

// #32 {root}/core/java/ android.app.servertransaction.PauseActivityItem (L42)
public void execute(ClientTransactionHandler client, IBinder token, 
        PendingTransactionActions pendingActions) {
    ...
    client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions, 
            "PAUSE_ACTIVITY_ITEM"); // 调用#33
    ...
}

【L-05】client.handlePauseActivity(…);
client是一个ClientTransactionHandler类型的方法参数,上文3.5节中曾经提到过ActivityThread类继承自ClientTransactionHandler类,所以此处实际执行的是ActivityThread类的handlePauseActivity()


3.11 handlePauseActivity@ActivityThread

handlePauseActivity()检查应用进程中需要pause的Activity是否实际存在,然后调用performPauseActivity()执行pause流程。

// #33 {root}/core/java/ android.app.ActivityThread (L3929)
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
        int configChanges, PendingTransactionActions pendingActions, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        ...
        performPauseActivity(r, finished, reason, pendingActions); // 调用#34
        ...
    }
}

【L-04】ActivityClientRecord r = mActivities.get(token);
mActivities是一个ArrayMap<IBinder, ActivityClientRecord>类型的成员变量。这个Map的键类型是匿名Binder实体类Token(它是ActivityRecord的内部类),其主要作用是标识一个Activity在AMS进程中对应的ActivityRecord对象。而它的值类型则是ActivityClientRecord,其主要作用是描述一个Activity在应用进程中的相关信息36。由键和值的类型可以看出,mActivities变量维护了同一个Activity在AMS进程(对应ActivityRecord)与应用进程(对应ActivityClientRecord)之间的映射关系。

【L-07】if (r != null) { … }
r是一个ActivityClientRecord类型的局部变量,它不仅直接持有Activity的引用37,还额外记录了应用进程中与Activity相关的信息。通常情况下r就是ResumeActivity对应的ActivityClientRecord对象,它的值不为null,从而后续代码进入if分支。


3.12 performPauseActivity@ActivityThread

performPauseActivity()首先判断Activity是否仍在运行(即尚未调用finish())。只要Activity仍在运行(即使已经处于pause状态),就一定会调用performPauseActivityIfNeeded()尝试执行pause流程。

// #34 {root}/core/java/ android.app.ActivityThread (L3962)
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason, 
        PendingTransactionActions pendingActions) {
    if (r.paused) {
        if (r.activity.mFinished) 
            return null;
        ...
    }
    ...
    performPauseActivityIfNeeded(r, reason); // 调用#35
    ...
}


3.13 performPauseActivityIfNeeded@ActivityThread

当Activity未处于pause状态时,performPauseActivityIfNeeded()委托Instrumentation对象完成Activity的pause流程。

// #35 {root}/core/java/ android.app.ActivityThread (L4013)
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    if (r.paused) 
        return;
    ...
    mInstrumentation.callActivityOnPause(r.activity); // 调用#36
    ...
    r.setState(ON_PAUSE);
}

【L-03】if (r.paused){ … }
上文3.12节中提到过,即使Activity已经处于pause状态,caller方法performPauseActivity()也仍然会调用performPauseActivityIfNeeded()。所以此处再次检查Activity是否处于pause状态,而这也正是方法名带有“IfNeeded”的原因。

【L-06】mInstrumentation.callActivityOnPause(r.activity);
mInstrumentation是一个Instrumentation类型的成员变量。上文1.2节中提到过,它扮演着应用进程的“管家”的角色,所有与Activity生命周期有关的操作最终都会委托给它来完成。


3.14 callActivityOnPause@Instrumentation

callActivityOnPause()没有任何额外的操作,只是简单地通知Activity执行pause流程。

// #36 {root}/core/java/ android.app.Instrumentation (L1464)
public void callActivityOnPause(Activity activity) {
    activity.performPause(); // 调用#37
}


3.15 performPause@Activity

performPause()终于调用了令人熟悉而又期待的onPause()。至此为止,ResumedActivity的pause流程终于分析完毕。

// #37 {root}/core/java/ android.app.Activity (L7325)
final void performPause() {
    ...
    onPause();
    ...
}


4 创建Activity所属的新进程

本节的调用流程如下图所示:

ActivityStack [ASS] [AMS] Process ZygoteProcess [38] startSpecificActivityLocked() [39-43] startProcessLocked() [44] startProcess() [45] start() [46] start() [47] startViaZygote() [48] zygoteSendArgsAndGetResult() ActivityStack [ASS] [AMS] Process ZygoteProcess

注:[ASS]=ActivityStackSupervisor, [AMS]=ActivityManagerService。


4.1 startSpecificActivityLocked@ActivityStackSupervisor

当ResumedActivity的pause流程执行完毕后,(AMS进程)就可以正式启动目标Acitivity,该过程的入口方法正是上文2.9节中提到的startSpecificActivityLocked()。该方法首先检查Activity所属的应用进程是否已经存在,如果存在则调用realStartActivityLocked()在对应的进程中执行Activity的启动流程(即直接跳转到本文的5.6节),反之则先调用startProcessLocked()创建一个新的进程。

// #38 {root}/services/core/java com.android.server.am.ActivityStackSupervisor (L1678)
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    ProcessRecord app = mService.getProcessRecordLocked(r.processName, 
            r.info.applicationInfo.uid, true);
    ...
    if (app != null && app.thread != null) {
        ...
        realStartActivityLocked(r, app, andResume, checkConfig);
        return;
    }
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", 
            r.intent.getComponent(), false, false, true); // 调用#39
}

【L-06】if (app != null && app.thread != null) { … }
appapp.thread分别为ProcessRecord和IApplicationThread类型的对象。此处的判断条件在上文2.9节3.1节中都曾经分析过,它用于检查Activity所属的进程是否存在。为了更加全面地展示Activity的启动流程,本文假定对应的进程尚未创建,也即不满足if语句的判断条件。


4.2 startProcessLocked@ActivityManagerService

startProcessLocked()经过一系列复杂的重载调用,最终会调用startProcess()启动进程。

// #39 {root}/services/core/java com.android.server.am.ActivityManagerService (L4060)
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 
        boolean allowWhileBooting, boolean isolated, boolean keepIfLarge) {
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, 
            hostingType, hostingName, allowWhileBooting, isolated, 0, keepIfLarge, 
            null, null, null, null); // 调用#40
}

// #40 {root}/services/core/java com.android.server.am.ActivityManagerService (L4071)
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    ...
    final boolean success = startProcessLocked(app, hostingType, hostingNameStr, 
            abiOverride); // 调用#41
    ...
}

// #41 {root}/services/core/java com.android.server.am.ActivityManagerService (L4194)
private final boolean startProcessLocked(ProcessRecord app, String hostingType, 
        String hostingNameStr, String abiOverride) {
    return startProcessLocked(app, hostingType, hostingNameStr, false, abiOverride); // 调用#42
}

// #42 {root}/services/core/java com.android.server.am.ActivityManagerService (L4204)
private final boolean startProcessLocked(ProcessRecord app, String hostingType, 
        String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
    ...
    final String entryPoint = "android.app.ActivityThread";
    return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids, runtimeFlags, 
            mountExternal, seInfo, requiredAbi, instructionSet, invokeWith, startTime); // 调用#43
    ...
}

// #43 {root}/services/core/java com.android.server.am.ActivityManagerService (L4400)
private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint, 
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal, String seInfo, 
        String requiredAbi, String instructionSet, String invokeWith, long startTime) {
    ...
    if (mConstants.FLAG_PROCESS_START_ASYNC) {
        ...
        mProcStartHandler.post(() -> {
            ...
            final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint, 
                    app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo, 
                    requiredAbi, instructionSet, invokeWith, app.startTime); // 调用#44
            ...
        });
        ...
    }
    else {
        ...
        final ProcessStartResult startResult = startProcess(hostingType, entryPoint, 
                app, uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, 
                instructionSet, invokeWith, startTime); // 调用#44
        ...
    }
}

【L-31】final String entryPoint = “android.app.ActivityThread”;
entryPoint参数表示新进程的入口类,此处该值被设置为android.app.ActivityThread,从而使ActivityThread类的main方法成为新进程的启动入口38

【L-42】if (mConstants.FLAG_PROCESS_START_ASYNC) { … }
mConstants是一个ActivityManagerConstants类型的成员变量,它记录了大量与AMS行为有关的常量和配置参数。其中,FLAG_PROCESS_START_ASYNC是一个boolean变量,标志着新进程的启动过程是否需要异步执行(默认值为true)。实际上从startProcessLocked()的代码中可以看出,无论是同步还是异步执行,最终都将调用同一个startProcess(),所以此处该变量的实际取值并不影响对后续调用流程的分析。


4.3 startProcess@ActivityManagerService

startProcess()根据触发进程创建的组件类型,执行不同的后续启动流程。在本文分析的执行流程中,后续调用的方法为Process.start()

// #44 {root}/services/core/java com.android.server.am.ActivityManagerService (L4463)
private ProcessStartResult startProcess(String hostingType, String entryPoint, ProcessRecord app, 
        int uid, int[] gids, int runtimeFlags, int mountExternal, String seInfo, String requiredAbi, 
        String instructionSet, String invokeWith, long startTime) {
    ...
    if (hostingType.equals("webview_service")) {
        ...
    }
    else {
        startResult = Process.start(entryPoint, app.processName, uid, uid, gids, 
                runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, 
                requiredAbi, instructionSet, app.info.dataDir, invokeWith, 
                new String[] { PROC_START_SEQ_IDENT + app.startSeq }); // 调用#45
    }
    ...
}

【L-06】if (hostingType.equals(“webview_service”)) { … }
hostingType是一个String类型的方法参数,它记录了新进程的创建是由于启动何种组件而触发的。例如,当由于启动一个Activity而需要创建新进程时,它的值为“activity”;同理,当由于启动一个Service而需要创建新进程时,它的值为“service”39。显然,对于本文分析的Activity启动流程,该值不可能为“webview_service”,从而后续代码执行else分支。


4.4 start@Process

start()通过Socket通信将新进程的创建请求发送给zygote进程处理。Android系统在启动时,首先会解析init.rc配置文件并启动zygote进程,然后由zygote进程负责孵化(fork)系统服务进程system_server和所有的应用程序进程40。也就是说,zygote进程的主要职责是作为一个Socket的server端,接收和处理各种进程创建的请求41

// #45 {root}/core/java/ android.os.Process (L479)
public static final ProcessStartResult start(final String processClass, final String niceName, 
        int uid, int gid, int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, 
        String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, 
        String[] zygoteArgs) {
    return zygoteProcess.start(processClass, niceName, uid, gid, gids, runtimeFlags, 
            mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, 
            invokeWith, zygoteArgs); // 调用#46
}

【L-06】return zygoteProcess.start(…);
zygoteProcess是一个ZygoteProcess类型的成员变量,它用于维护客户端进程与zygote进程建立的Socket连接。实际上ZygoteProcess类内部维护了两个Socket连接42,分别是主要连接mSocket和次要连接mSecondarySocket。当主要连接无法正常使用时,将尝试使用次要连接来进行通信。


4.5 start@ZygoteProcess

作为ZygoteProcess类对外公开的API方法,start()调用私有方法startViaZygote()完成新进程的创建。

// #46 {root}/core/java/ android.os.ZygoteProcess (L220)
public final Process.ProcessStartResult start(final String processClass, final String niceName,
        int uid, int gid, int[] gids, int runtimeFlags,    int mountExternal, int targetSdkVersion, 
        String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith,
        String[] zygoteArgs) {
    ...
    return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, 
            mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir,
            invokeWith, false, zygoteArgs); // 调用#47
    ...    
}


4.6 startViaZygote@ZygoteProcess

startViaZygote()计算并配置启动应用进程用所需的各种参数,然后调用zygoteSendArgsAndGetResult()将这些参数通过Socket发送给zygote进程进行处理43

// #47 {root}/core/java/ android.os.ZygoteProcess (L357)
private Process.ProcessStartResult startViaZygote(final String processClass, final String niceName,
        final int uid, final int gid, final int[] gids, int runtimeFlags, int mountExternal, 
        int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, 
        String invokeWith, boolean startChildZygote, String[] extraArgs) throws ZygoteStartFailedEx {
    ArrayList<String> argsForZygote = new ArrayList<String>();
    argsForZygote.add("--runtime-args");
    argsForZygote.add("--setuid=" + uid);
    argsForZygote.add("--setgid=" + gid);
    argsForZygote.add("--runtime-flags=" + runtimeFlags);
    ...
    return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); // 调用#48
}

【L-12】return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), …);
zygoteSendArgsAndGetResult()的第一个参数又调用了openZygoteSocketIfNeeded(),后者负责打开同zygote进程的Socket通信44。上文4.4节中提到过,ZygoteProcess类同时维护了主要连接mSocket和次要连接mSecondarySocket,所以openZygoteSocketIfNeeded()将依次调用它们的conncect()方法直到获取一个可用的连接,并且还会根据当前的ABI(CPU基于其支持的指令集所提供的二进制接口,可以简单理解为对于不同CPU架构的交互规则描述45)来选择与zygote(32位的zygote进程)还是zygote64(64位的zygote进程)进行通信46


4.7 zygoteSendArgsAndGetResult@ZygoteProcess

zygoteSendArgsAndGetResult()利用InputStream和OutputStream发送和接收数据,实现与zygote进程的Socket通信。上文4.2节中提到,新进程的入口entryPoint是android.app.ActivityThread类,所以新进程创建成功后会在主线程中调用ActivityThread类的main方法进行初始化,然后继续在应用进程中完成目标Acitivity的启动流程。

// #48 {root}/core/java/ android.os.ZygoteProcess (L280)
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, 
        ArrayList<String> args) throws ZygoteStartFailedEx {
    ...
    int sz = args.size();
    ...
    final BufferedWriter writer = zygoteState.writer;
    final DataInputStream inputStream = zygoteState.inputStream;
    writer.write(Integer.toString(args.size()));
    writer.newLine();
    for (int i = 0; i < sz; i++) {
        String arg = args.get(i);
        writer.write(arg);
        writer.newLine();
    }
    writer.flush();
    Process.ProcessStartResult result = new Process.ProcessStartResult();
    result.pid = inputStream.readInt();
    result.usingWrapper = inputStream.readBoolean();
    if (result.pid < 0) 
        throw new ZygoteStartFailedEx("fork() failed");
    return result;
    ...
}

【L-18】result.pid = inputStream.readInt();
当zygote进程成功创建新进程后,会返回该进程的pid。


5 应用进程启动Activity

本节的调用流程如下图所示:

(VM) ActivityThread [AMS] [ASS] [49] main() [50] attach() [51] attach() [52] attachApplicationLocked() [53] attachApplicationLocked() [54] realStartActivityLocked() (VM) ActivityThread [AMS] [ASS]


[ASS] LaunchActivityItem ActivityThread Instrumentation Activity [55] execute() [56] handleLaunchActivity() [57] performLaunchActivity() [58] callActivityOnCreate() [59-60] performCreate() [-] onCreate() [ASS] LaunchActivityItem ActivityThread Instrumentation Activity


[ASS] ResumeActivityItem ActivityThread Activity Instrumentation [61] execute() [62] handleResumeActivity() [63] performResumeActivity() [64] performResume() [65] callActivityOnResume() [-] onResume() [ASS] ResumeActivityItem ActivityThread Activity Instrumentation

注:
(1)新进程的底层创建过程由虚拟机负责调度,此处第一幅流程图中用“(VM)”虚指触发流程的起始对象。
(2)为了排版美观,此处将整个流程拆分为三个时序图进行绘制,分别展示ActivityThread的初始化和绑定流程、Activity的create流程、Activity的resume流程。
(3)[AMS]=ActivityManagerService, [ASS]=ActivityStackSupervisor。
(4)onCreate()和onResume()对于理解执行流程具有重要意义,所以这两个方法被标注在流程图中。由于下文并没有具体对这两个方法进行分析,所以它们的方法编号为“-”。


5.1 main@ActivityThread

上文4.2节中提到应用进程的入口entryPoint被设置为android.app.ActivityThread类,所以进程创建成功后,会首先在主线程中调用ActivityThread的main()执行初始化流程。

// #49 {root}/core/java/ android.app.ActivityThread (L6623)
public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();
    ...
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq); // 调用#50
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    ...
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

【L-04】Looper.prepareMainLooper();
Looper.prepareMainLooper()最主要的作用是调用Looper.prepare(false)为主线程创建一个消息循环对象(注意此时消息循环尚未启动),而这也正是主线程中不需要显式创建Looper消息循环就能直接创建(绑定到当前线程Looper的)Handler对象的原因47

【L-07】thread.attach(false, startSeq);
在启动消息循环之前,会通过调用thread.attach()来绑定应用进程。

【L-09】sMainThreadHandler = thread.getHandler();
sMainThreadHandler是一个Handler类型的成员变量,其实它就是上文3.6节中提到过的(Activity的内部类)H类。如果此时H类尚未初始化,thread.getHandler()最终会通过调用H类的构造器来确保完成它的初始化。

【L-11】Looper.loop();
Looper.loop()启动消息循环,它的内部实现是一个“for死循环”,所以正常情况下它永远不会主动终止并退出。消息循环的内部维护了一个消息队列,如果队列中没有消息,主线程会释放CPU资源进入休眠状态,一旦有消息抵达时,主线程会被唤醒并处理消息。由于主线程大多数时候都处于休眠状态,所以消息循环本身并不会导致消耗大量CPU资源或引发UI卡顿48。至于开发中可能出现的ANR(应用程序无响应),其本质是某一个消息(的处理)阻塞了Looper.loop(),而不是Looper.loop()阻塞了消息(的处理)。也就是说,Looer.loop()方法可能会引起主线程的阻塞,但只要消息循环没有被阻塞,就能一直处理事件而不会产生ANR异常49

【L-12】throw new RuntimeException(…);
正常情况下,Looper消息循环一经启动就不会主动退出。如果由于某些特殊情况导致循环退出,那么主线程也会随时结束,此时便会抛出运行时异常。


5.2 attach@ActivityThread

attach()根据boolean参数system的值执行不同的流程。在本文分析的执行流程中,该值一定为false,所以后续实际的执行流程主要包括:通过AMS为应用绑定Application、添加一个与垃圾回收有关的观察者对象、为根View添加config回调用于接收config变化相关的信息50。其中,与Activity启动关系最为密切的是用于绑定Application的attachApplication()

// #50 {root}/core/java/ android.app.ActivityThread (L6478)
private void attach(boolean system, long startSeq) {
    ...
    if (!system) {
        ...
        final IActivityManager mgr = ActivityManager.getService();
        mgr.attachApplication(mAppThread, startSeq); // IPC调用#51
        ...
        BinderInternal.addGcWatcher(new Runnable() { ... });
    } 
    else {
        ...
    }
    ...
    ViewRootImpl.ConfigChangedCallback configChangedCallback = 
            (Configuration globalConfig) -> { ... };
    ViewRootImpl.addConfigCallback(configChangedCallback);
}

【L-04】if (!system) { … }
system是一个boolean类型的方法参数,由于caller方法main()传入的值为false,所以后续代码执行if分支。

【L-06】final IActivityManager mgr = ActivityManager.getService();
ActivityManager.getService()方法在上文1.3节中曾经分析过,它返回IActivityManager接口的Binder代理对象,用于应用进程向AMS发送请求。

【L-07】mgr.attachApplication(mAppThread, startSeq);
Binder代理对象mgr通过AIDL调用AMS的attachApplication(),该方法的第一个参数mAppThread就是需要为应用绑定的ApplicationThread对象。


5.3 attachApplication@ActivityManagerService

attachApplication()获取应用进程的callingPid、callingUid等参数,然后将其传递给attachApplicationLocked()执行后续流程。

// #51 {root}/services/core/java com.android.server.am.ActivityManagerService (L7932)
public final void attachApplication(IApplicationThread thread, long startSeq) {
    ...
    int callingPid = Binder.getCallingPid();
    final int callingUid = Binder.getCallingUid();
    final long origId = Binder.clearCallingIdentity();
    attachApplicationLocked(thread, callingPid, callingUid, startSeq); // 调用#52
    ...
}


5.4 attachApplicationLocked@ActivityManagerService

attachApplicationLocked()的流程相对复杂,主要包括对Application进行一系列的合法性校验和参数配置、调用thread.bindApplication()通知应用进程执行Application的初始化流程、调用mStackSupervisor.attachApplicationLocked()启动栈顶Activity51

// #52 {root}/services/core/java com.android.server.am.ActivityManagerService (L7572)
private final boolean attachApplicationLocked(IApplicationThread thread, int pid,
        int callingUid, long startSeq) {
    ProcessRecord app;
    ...
    if (app.isolatedEntryPoint != null) {
        ...
    }
    else if (app.instr != null) {
        thread.bindApplication(processName, appInfo, providers, app.instr.mClass, 
                profilerInfo, app.instr.mArguments, app.instr.mWatcher, 
                app.instr.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, 
                enableTrackAllocation, isRestrictedBackupMode || !normalMode, 
                app.persistent, new Configuration(getGlobalConfiguration()), 
                app.compat, getCommonServicesLocked(app.isolated), 
                mCoreSettingsObserver.getCoreSettingsLocked(), 
                buildSerial, isAutofillCompatEnabled);
    }
    else {
        thread.bindApplication(processName, appInfo, providers, null, 
                profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, 
                enableTrackAllocation, isRestrictedBackupMode || !normalMode, 
                app.persistent, new Configuration(getGlobalConfiguration()), 
                app.compat, getCommonServicesLocked(app.isolated), 
                mCoreSettingsObserver.getCoreSettingsLocked(), 
                buildSerial, isAutofillCompatEnabled);
    }
    ...
    if (mStackSupervisor.attachApplicationLocked(app)) { ... } // 调用#53
    ...
}

【L-06】if (app.isolatedEntryPoint != null) { … }
app.isolatedEntryPoint是ProcessRecord类一个String类型的成员变量,它对应于Manifest中Service的android:isolatedProcess属性,该值为true意味着服务会在一个特殊的进程下运行,该进程将与系统其它进程分开并且没有自己的权限52。由于此处进程是为启动Activity而创建的,这个属性没有实际意义, 所以app.isolatedEntryPoint为null,后续代码会执行else if或者else分支。无论实际执行哪个分支,都会调用同一个thread.bindApplication()初始化进程的Application,其中的区别仅仅是传入的参数值不同。

【L-10】thread.bindApplication(…);
thread是IApplicationThread接口的Binder代理对象,此处AMS通过AIDL调用应用进程ApplicationThread(上文3.4节中提到过它是ActivityThread的内部类)的bindApplication()。也就是说,AMS并不会“亲自”执行Application的初始化流程,而是简单地配置初始化参数后通知应用进程自行处理53。与上文3.5节中提到的ResumedActivity的pause流程类似,应用进程在收到AMS的通知后,通过H类发送和处理对应的消息。受篇幅限制,此处不再继续深入解析应用进程中Application初始化的后续流程。

【L-29】if (mStackSupervisor.attachApplicationLocked(app)) { … }
attachApplicationLocked()检查当前栈顶可见的Activity是否为当前进程需要启动的Activity(本文分析的执行流程中,这个判断条件显然满足),然后启动该Activity。


5.5 attachApplicationLocked@ActivityStackSupervisor

attachApplicationLocked()遍历当前获得焦点的Activity栈,若其中存在属于当前进程但尚未启动的Activity,则调用realStartActivityLocked()执行该Activity的启动流程。

// #53 {root}/services/core/java com.android.server.am.ActivityStackSupervisor (L971)
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    ...
    stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
    final ActivityRecord top = stack.topRunningActivityLocked();
    final int size = mTmpActivityList.size();
    for (int i = 0; i < size; i++) {
        final ActivityRecord activity = mTmpActivityList.get(i);
        if (activity.app == null && app.uid == activity.info.applicationInfo.uid 
                && processName.equals(activity.processName)) {
            ...
            if (realStartActivityLocked(activity, app, top == activity, true)) { ... } // 调用#54
            ...
        }
    }
    ...
}

【L-04】stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
stack是一个ActivityStack类型的局部变量,它表示当前获得焦点的Activity栈;mTmpActivityList是一个ArrayList<ActivityRecord>类型的成员变量。由于getAllRunningVisibleActivitiesLocked()是一个没有返回值的方法,所以它在执行过程中会获取Activity栈上所有处于运行状态的可见Activity对应的ActivityRecord,并将结果添加到参数mTmpActivityList中。

【L-05】final ActivityRecord top = stack.topRunningActivityLocked();
局部变量top用于记录栈顶正在运行的Activity,也即需要启动的Activity。

【L-09】if (…) { … }
此处遍历mTmpActivityList中的所有Activity,如果某个Activity尚未启动(即满足判断条件activity.app == null),则继续检查它是否属于当前进程(即是否满足剩余的判断条件)。当以上条件均满足时,会调用realStartActivityLocked()启动这个Activity。

【L-12】if (realStartActivityLocked(activity, app, top == activity, true)) { … }
realStartActivityLocked()在上文4.1节中曾经出现过——当ResumedActivity的pause流程执行完毕后,如果需要启动的Activity所属的应用进程已经存在,就会直接调用该方法。只不过,本文为了“更加全面地展示Activity的启动流程”,假定需要创建新的进程并“插入”了相关流程的分析章节。也就是说,在“创建新进程”上绕了一个大圈子后,启动Activity的流程终于重新回到了“原本的起点”。


5.6 realStartActivityLocked@ActivityStackSupervisor

realStartActivityLocked()创建一个ClientTransaction对象并设置其回调方法和Acitivity状态请求,然后执行该transaction。上文3.2~3.10节在分析ResumeActivity的pause流程时,曾经详细介绍过transaction的执行流程,由于回调方法会先于状态请求执行(参见上文3.8节),所以该流程最终会依次调用LaunchActivityItem和ResumeActivityItem的execute()

// #54 {root}/services/core/java com.android.server.am.ActivityStackSupervisor (L1377)
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, 
        boolean checkConfig) throws RemoteException {
    ...
    final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken);
    clientTransaction.addCallback(LaunchActivityItem.obtain(
            new Intent(r.intent), System.identityHashCode(r), r.info, 
            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) 
        lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
    else 
        lifecycleItem = PauseActivityItem.obtain();
    clientTransaction.setLifecycleStateRequest(lifecycleItem);
    mService.getLifecycleManager().scheduleTransaction(clientTransaction); // 最终调用#55、#61
    ...
}

【L-06】clientTransaction.addCallback(LaunchActivityItem.obtain(…));
LaunchActivityItem.obtain()创建一个LaunchActivityItem对象,并且该对象被添加到了transaction的回调方法中。

【L-13】if (andResume) { … }
5.5节提到的caller方法()attachApplicationLocked中,传入的参数andResume为条件判断语句top == activity。显然,对于需要启动的Activity该值为true,所以transaction的Activity状态请求被设置为ResumeActivityItem对象。


5.7 execute@LaunchActivityItem

与上文3.10节的流程类似,LaunchActivityItem类的execute()获取Activity在应用进程中对应的ActivityClientRecord对象,然后将其传递给ActivityThread类的handleLaunchActivity()进行处理。

// #55 {root}/core/java/ android.app.servertransaction.LaunchActivityItem (L71)
public void execute(ClientTransactionHandler client, IBinder token, 
        PendingTransactionActions pendingActions) {
    ...
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, 
            mPendingResults, mPendingNewIntents, mIsForward, mProfilerInfo, client);
    client.handleLaunchActivity(r, pendingActions, null ); // 调用#56
    ...
}

【L-08】client.handleLaunchActivity(…);
client是一个ClientTransactionHandler类型的方法参数,该类继承自ActivityThread类,所以实际调用的是ActivityThread类的handleLaunchActivity()


5.8 handleLaunchActivity@ActivityThread

handleLaunchActivity()初始化Android窗口管理服务WindowManagerService(即WMS)的Binder代理对象54,然后调用performLaunchActivity()执行Activity的启动流程。

// #56 {root}/core/java/ android.app.ActivityThread (L3024)
public Activity handleLaunchActivity(ActivityClientRecord r, 
        PendingTransactionActions pendingActions, Intent customIntent) {
    ...
    WindowManagerGlobal.initialize();
    final Activity a = performLaunchActivity(r, customIntent); // 调用#57
    ...
}


5.9 performLaunchActivity@ActivityThread

performLaunchActivity()的主要流程包括获取需要启动的Activity的相关信息、通过类加载器加载Activity对应的类并创建对象、(在必要的情况下)尝试创建Application对象、创建并初始化Activity对应的Context对象、委托Instrumentation对象执行Activity的create流程。

// #57 {root}/core/java/ android.app.ActivityThread (L2808)
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo;
    ...
    ComponentName component = r.intent.getComponent();
    ...
    if (r.activityInfo.targetActivity != null) 
        component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity);
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    ...
    java.lang.ClassLoader cl = appContext.getClassLoader();
    activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    ...
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    if (activity != null) {
        ...
        appContext.setOuterContext(activity);
        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);
        ...
        if (r.isPersistable()) 
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        else 
            mInstrumentation.callActivityOnCreate(activity, r.state); // 调用#58
        ...
    }
    r.setState(ON_CREATE);
    ...
}

【L-09】ContextImpl appContext = createBaseContextForActivity(r);
ContextImpl类继承自Context抽象类,它为Activity等组件提供context的基础实现。此处通过调用createBaseContextForActivity(),创建了一个与Activity对应的ContextImpl对象。

【L-13】activity = mInstrumentation.newActivity(…);
mInstrumentation是一个Instrumentation类型的成员变量,它的newActivity()首先获取Activity的类名,然后通过类加载器cl将对应的类加载到虚拟机中,最后利用反射创建Activity的实例。

【L-15】Application app = r.packageInfo.makeApplication(false, mInstrumentation);
makeApplication()检查进程的Application对象是否存在,如果不存在则尝试执行对应的创建流程。由于上文5.4节中调用的thread.bindApplication()已经完成了Application的初始化流程55,所以此处并不需要重复执行创建流程。

【L-18】appContext.setOuterContext(activity);
setOuterContext()将ContextImpl类的mOuterContext成员变量设置为Activity对象,从而使得ContextImpl能够将特定的操作转发给它所关联的Activity进行处理56

【L-19】activity.attach(…);
attach()完成了Activity对象的大部分成员变量的初始化流程57,也就是说,此处传入的部分参数的引用会被Activity所持有。例如,第二个参数this和第三个参数getInstrumentation()分别用于初始化Activity对象的成员变量mMainThreadmInstrumentation58

【L-23】if (r.isPersistable()) { … }
ActivityClientRecord对象的isPersistable()检查它的boolean成员变量activityInfo.persistableMode的值(对应于Manifest中Application标签的android:persistent属性),该值为true表示对应的Application具有持久性——它会自系统启动后“持久地”保持运行直到关机为止,并且在运行出现异常时会自动地重新启动59。本文假定需要启动的Activity不属于持久应用,所以后续将执行else分支并调用传入两个参数的callActivityOnCreate()


5.10 callActivityOnCreate@Instrumentation

callActivityOnCreate()的默认实现是简单地将后续执行流程委托给Activity对象的performCreate()处理。

// #58 {root}/core/java/ android.app.Instrumentation (L1269)
public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle); // 调用#59
    postPerformCreate(activity);
}


5.11 performCreate@Activity

performCreate()经过重载调用,最终会调用onCreate()。至此为止,需要启动的Activity的create流程终于分析完毕。

// #59 {root}/core/java/ android.app.Activity (L7126)
final void performCreate(Bundle icicle) {
    performCreate(icicle, null); // 调用#60
}

// #60 {root}/core/java/ android.app.Activity (L7130)
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    ...
    if (persistentState != null) 
        onCreate(icicle, persistentState); 
    else 
        onCreate(icicle);
    ...
}


5.12 execute@ResumeActivityItem

上文5.6节中提到realStartActivityLocked()会依次调用LaunchActivityItem和ResumeActivityItem的execute(),两者分别对应对Activity的create和resume流程。所以,当create流程处理完毕后,接下来就会调用ResumeActivityItem的execute()。到这里也许有些读者会感到奇怪,Activity的生命周期应该遵循“onCreate() -> onStart() -> onResume()”的回调顺序,为什么这里看起来跳过了onStart()回调方法?其实,与start状态相关的回调并没有被跳过,而这要“归功”于上文3.9节中提到的cycleToPath()——当TransactionExecutor调用executeLifecycleState()处理transaction的状态请求时,cycleToPath()会首先检查当前状态和请求状态之间是否存在中间状态。此处在create和resume之间存在一个start状态,所以cycleToPath()会额外地调用handleStartActivity()处理start状态60。受篇幅限制,此处略去对cycleToPath()方法的详细分析,而直接从后续调用的ResumeActivityItem的execute()开始分析。

// #61 {root}/core/java/ android.app.servertransaction.ResumeActivityItem (L48)
public void execute(ClientTransactionHandler client, IBinder token, 
        PendingTransactionActions pendingActions) {
    ...
    client.handleResumeActivity(token, true, mIsForward, "RESUME_ACTIVITY"); // 调用#62
    ...
}

【L-05】client.handleResumeActivity(…);
与上文3.10节5.7节分析过的PauseActivityItem和LaunchActivityItem的执行流程类似,client参数的实际类型是ActivityThread,所以后续调用的是ActivityThread类的handleResumeActivity()


5.13 handleResumeActivity@ActivityThread

handleResumeActivity()首先调用handleLaunchActivity()执行Activity的resume流程,然后对Activity的视图进行计算和绘制61,最后为线程Looper中的消息队列绑定一个与内存回收有关的空闲消息处理器。

// #62 {root}/core/java/ android.app.ActivityThread (L3808)
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
        String reason) {
    ...
    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, 
            reason); // 调用#63
    if (r == null) 
        return;
    final Activity a = r.activity;
    ...
    if (r.window == null && !a.mFinished && willBeVisible) {
        ...
        ViewManager wm = a.getWindowManager();
        ...
        if (a.mVisibleFromClient) {
            if (!a.mWindowAdded) {
                a.mWindowAdded = true;
                wm.addView(decor, l);
            } 
            else {
                ...
            }
        }
    }
    Looper.myQueue().addIdleHandler(new Idler());
}

【L-13】ViewManager wm = a.getWindowManager();
wm是一个WindowManager类型的局部变量,该类实现了ViewManager 接口,主要用于管理窗口的状态、属性以及处理view的增加、删除和更新操作等62

【L-18】wm.addView(…);
addView()创建了一个ViewRootImpl对象(作为连接WindowManager与根视图DecorView的纽带62),然后通过该对象完成所有视图控件的测量、布局和绘制流程63

【L-25】Looper.myQueue().addIdleHandler(new Idler());
Idler类是ActivityThread类的内部类,它是一个实现MessageQueue.IdleHandler接口的空闲消息处理器。当消息队列处于没有消息需要处理的空闲状态时,就会调用与之绑定的IdleHandler对象的queueIdle()。此处Idler类的queueIdle()通过Binder代理对象调用AMS的activityIdle(),从而触发系统的内存回收操作64


5.14 performResumeActivity@ActivityThread

performResumeActivity()通过ActivityClientRecord对象获取需要启动的Activity对象,然后调用它的performResume()执行resume流程。

// #63 {root}/core/java/ android.app.ActivityThread (L3737)
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest, 
        String reason) {
    final ActivityClientRecord r = mActivities.get(token);
    ...
    r.activity.performResume(r.startsNotResumed, reason); // 调用#64
    ...
    r.setState(ON_RESUME);
    ...
}


5.15 performResume@Activity

performResume()首先检查并且确保需要启动的Activity尚未处于stop状态,然后委托Instrumentation对象执行Activity的resume流程。

// #64 {root}/core/java/ android.app.Activity (L7273)
final void performResume(boolean followedByPause, String reason) {
    performRestart(true, reason);
    ...
    mInstrumentation.callActivityOnResume(this); // 调用#65
    ...
}

【L-03】performRestart(…);
performRestart()检查Activity是否处于stop状态,如果是,则依次执行它的restart和start流程,从而使Activity重新恢复为start状态65


5.16 callActivityOnResume@Instrumentation

callActivityOnResume()调用Activity的onResume(),至此为止Activity的整个启动流程全部分析完毕。

// #65 {root}/core/java/ android.app.Instrumentation (L1410)
public void callActivityOnResume(Activity activity) {
    ...
    activity.onResume();
    ...
}


总结

调用Activity.startActivity()启动一个Activity的执行流程简要总结如下:
(1)应用进程向AMS发送Activity启动请求。
(2)AMS进行一系列准备工作,主要包括合法性检查和启动参数解析。
(3)AMS根据Activity的启动模式判断栈顶Activity实例能否复用。若能够复用,则通知栈顶Activity所属的应用进程回调onNewIntent(),启动流程结束;否则,继续执行步骤(4)。
(4)AMS判断当前是否存在resume状态的Activity。若该Activity存在,则通过IPC通知它所属应用进程回调onPause()。
(5)AMS判断目标Activity所属的进程是否已经存在。若进程尚未创建,则请求Zygote创建一个新进程,然后在其主线程中调用ActivityThread.main()完成进程的初始化。
(6)Activity所属的目标进程依次回调onCreate()、onStart()、onResume(),从而完成启动流程。


参考文献


  1. Activity启动流程分析.
    https://juejin.im/post/5b1e87eae51d4506c95ed1c9 ↩︎

  2. Activity中mParent 成员变量是如何被赋值的.
    https://blog.csdn.net/yawinstake/article/details/53955709 ↩︎

  3. 关于activitygroup过时,用frament替换操作.
    https://blog.csdn.net/xiangzhihong8/article/details/38370237 ↩︎

  4. 【凯子哥带你学Framework】Activity启动过程全解析.
    https://www.aliyun.com/jiaocheng/13760.html ↩︎

  5. Activity启动过程源码分析.
    https://www.jianshu.com/p/86b405129385 ↩︎

  6. java HelloWorld.
    https://blog.csdn.net/gcxzflgl/article/details/70194291 ↩︎

  7. Android的UI主线程是ActivityThread吗?.
    https://blog.csdn.net/chwnpp2/article/details/70338215 ↩︎

  8. ActivityThread是UI线程吗,它并没有继承自Thread?.
    https://www.zhihu.com/question/49989115 ↩︎

  9. startActivity( ) 与startActivityForResult( )的区别.
    https://blog.csdn.net/guyuealian/article/details/46894435 ↩︎

  10. Android startActivity 流程分析.
    https://www.heqiangfly.com/2016/06/10/android-source-code-analysis-activity-start-process/ ↩︎

  11. 关于ActivityThread和ApplicationThread的解析.
    https://blog.csdn.net/cengdong/article/details/69488836 ↩︎

  12. Activity启动详解.
    https://blog.csdn.net/tyuiof/article/details/80010069 ↩︎

  13. Android 源码解析之Singleton.
    https://blog.csdn.net/loveBuZhiDao/article/details/79743072 ↩︎

  14. Android Service Manager分析.
    https://blog.csdn.net/wlwl0071986/article/details/50977573 ↩︎

  15. AIDL原理解析.
    https://blog.csdn.net/xude1985/article/details/9232049/ ↩︎

  16. Activity的启动流程 Android5.1.1.
    https://blog.csdn.net/u010083774/article/details/50781357 ↩︎

  17. ActivityStackSupervisor.java关键信息解读.
    https://blog.csdn.net/u013543848/article/details/77198462 ↩︎

  18. ResolveInfo的用法.
    https://blog.csdn.net/xiaotian314/article/details/38423111 ↩︎

  19. resolveActivity解析.
    https://blog.csdn.net/rockstore/article/details/79717571 ↩︎

  20. ActivityRecord、TaskRecord、ActivityStack.
    https://blog.csdn.net/kebelzc24/article/details/53747506 ↩︎

  21. Android Frameworks系列(二) 彻底弄懂startActivity.
    https://blog.csdn.net/chenkai19920410/article/details/54344295 ↩︎

  22. Activity启动流程.
    https://www.jianshu.com/p/c9f66f665775 ↩︎

  23. ActivityStarter之startActivityUnchecked().
    https://blog.csdn.net/woai110120130/article/details/79779840 ↩︎

  24. Activity启动流程.
    https://www.jianshu.com/p/c9f66f665775 ↩︎

  25. ActivityStarter之startActivityUnchecked().
    https://blog.csdn.net/woai110120130/article/details/79779840 ↩︎

  26. Activity正常启动过程.
    http://www.360doc.com/content/17/0331/21/28309839_641818926.shtml ↩︎

  27. Android – Activity启动流程分析.
    https://blog.csdn.net/csdn_of_coder/article/details/78024696 ↩︎

  28. ActivityStarter之startActivityUnchecked().
    https://blog.csdn.net/woai110120130/article/details/79779840 ↩︎

  29. AMS的Activity管理情景1在现有task上启动到同一个task上.
    https://blog.csdn.net/woai110120130/article/details/80297745 ↩︎

  30. Android 开发艺术与探究 第一章 Activity 的生命周期和启动模式.
    https://blog.csdn.net/liweicai137/article/details/51055640 ↩︎

  31. Android6.0 AMS启动Activity(五) 在新进程中启动Activity.
    https://blog.csdn.net/kc58236582/article/details/52488080 ↩︎

  32. Activity工作流程.
    https://blog.csdn.net/sx154893743/article/details/51527484 ↩︎

  33. (Android 9.0)Activity启动流程源码分析.
    https://blog.csdn.net/lj19851227/article/details/82562115 ↩︎

  34. (Android 9.0)Activity启动流程源码分析.
    https://blog.csdn.net/lj19851227/article/details/82562115 ↩︎

  35. (Android 9.0)Activity启动流程源码分析.
    https://blog.csdn.net/lj19851227/article/details/82562115 ↩︎

  36. 深入理解Activity——Token之旅.
    https://blog.csdn.net/guoqifa29/article/details/46819377 ↩︎

  37. 利用反射拿到Android的整个Activity栈.
    https://www.jianshu.com/p/ac0b237bac03 ↩︎

  38. 如何创建App进程.
    https://www.jianshu.com/p/c09dc098d980 ↩︎

  39. android java进程管理(三)之apk进程的启动.
    https://blog.csdn.net/tonyandroid1984/article/details/70224783 ↩︎

  40. Android Zygote系统进程启动过程分析(Android N).
    https://blog.csdn.net/yin1031468524/article/details/56009583 ↩︎

  41. Android进程系列第二篇—Zygote进程的启动流程.
    https://www.jianshu.com/p/ab9b83a77af6 ↩︎

  42. Android进程系列第五篇—应用进程的创建流程.
    https://www.jianshu.com/p/be7e933927ed ↩︎

  43. 深入理解Activity启动流程(三)–Activity启动的详细流程1.
    https://blog.csdn.net/chen381051010/article/details/56844670 ↩︎

  44. zygote的分裂.
    https://www.cnblogs.com/wanyuanchun/p/3748912.html ↩︎

  45. Android ABI的浅析.
    https://www.jianshu.com/p/d2119b3880d8 ↩︎

  46. Android 7.1.2(Android N) Activity启动流程分析.
    https://www.jianshu.com/p/733664614fa2 ↩︎

  47. Handler详解系列(四)——利用Handler在主线程与子线程之间互发消息,handler详解.
    https://www.cnblogs.com/xgjblog/p/5258947.html ↩︎

  48. 关于Looper.loop()死循环???.
    https://blog.csdn.net/liuwei187/article/details/80477143 ↩︎

  49. Android面试:主线程中的Looper.loop()一直无限循环为什么不会造成ANR?.
    https://www.jianshu.com/p/cfe50b8b0a41 ↩︎

  50. (Android 9.0)Activity启动流程源码分析.
    https://blog.csdn.net/lj19851227/article/details/82562115 ↩︎

  51. 深入理解Activity启动流程(三)–Activity启动的详细流程2.
    https://blog.csdn.net/chen381051010/article/details/56844788 ↩︎

  52. 关于Android Service真正的完全详解,你需要知道的一切.
    https://blog.csdn.net/javazejian/article/details/52709857 ↩︎

  53. Context解析之Application实例化.
    https://www.jianshu.com/p/8bf42ea69d18 ↩︎

  54. Window的内部机制.
    https://www.jianshu.com/p/737a301c0f18 ↩︎

  55. 深入理解Activity启动流程(三)–Activity启动的详细流程2.
    https://blog.csdn.net/chen381051010/article/details/56844788 ↩︎

  56. Android应用程序窗口(Activity)的运行上下文环境(Context)的创建过程分析.
    https://blog.csdn.net/luoshengyang/article/details/8201936 ↩︎

  57. ActvitityThread中的performLaunchActivity(ActivityClientRecord r, Intent customIntent)解析.
    https://blog.csdn.net/a284266978/article/details/53782453 ↩︎

  58. Activity启动过程详解.
    https://blog.csdn.net/u012481172/article/details/49658633 ↩︎

  59. 说说Android应用的persistent属性.
    https://my.oschina.net/youranhongcha/blog/269591 ↩︎

  60. (Android 9.0)Activity启动流程源码分析.
    https://blog.csdn.net/lj19851227/article/details/82562115 ↩︎

  61. Activity到底是什么时候显示到屏幕上的呢?.
    https://www.300168.com/yidong/show-2370.html ↩︎

  62. View的工作原理 - Android开发艺术探索读书笔记(第四章).
    https://blog.csdn.net/goo_x/article/details/50644504 ↩︎ ↩︎

  63. Android中Activity启动过程探究.
    https://www.cnblogs.com/kross/p/4025075.html ↩︎

  64. 10.2.4 释放内存详解(1).
    http://book.51cto.com/art/201109/291366.htm ↩︎

  65. AMS对Activity的管理.
    https://blog.csdn.net/u010753159/article/details/52587591 ↩︎

猜你喜欢

转载自blog.csdn.net/hongchi110/article/details/82890180