阅读 583

Activity 启动流程

关于 Activity 启动流程的文章已经很多了,百度上一搜一大片。

但是这些文章要不就是讲解得太简单了,为了讲清楚流程而忽略了应该有的细节;要不就是过于深入细节,导致整篇文章的脉络不清晰,连 Activity 启动的主体流程都没有讲清楚。

通过这篇文章,我们来梳理一下 Activity 启动的整体流程以及其中我们应该注意的细节。

Activity 启动的整体流程

普通 Activity 的启动

普通 Activity 的启动就是通过调用 startActivity 函数启动一个新的 Activity。总体流程如下图:

未命名文件.jpg

其中涉及了两个进程,App 进程和 AMS 进程。整体步骤是:

  1. 启动者 Activity 向 Instrumentation 请求启动目标 Activity;
  2. Instrumentation 通过 AMS 在 App 进程的 IBinder 接口(IActivityManager),访问 AMS,此时 App 进程阻塞等待 AMS 进程的调用返回,采用的跨进程技术是 AIDL;
  3. AMS 进程会进行一系列的验证工作,如判断目标 Activity 实例是否已经存在、启动模式是什么、有没有在 AndroidManifest.xml 文件中注册等等;
  4. 当 AMS 的验证工作结束后,就会通过 ClientLifeCycleManager 发送事务给 App 进程,利用 App 进程在 AMS 进程的 IBinder 接口(IApplicationThread)访问 App 进程的 ApplicationThread,采用的跨进程技术是 AIDL;
  5. ApplicationThread 是 ActivityThread 的内部类。当 ApplicationThread 接收到来自 AMS 的事务后,会将事务直接转交给 ActivityThread 处理;
  6. ActivityThread 通过 Instrumentation 利用类加载器(反射)进行创建实例,同时利用 Instrumentation 回调目标 Activity 的生命周期。

介绍几个关键的类:

  • Instrumentation:Instrumentation 是 Activity 与外界联系的类(不是 Activity 本身的类都统称为外界)。目标 Activity 通过 Instrumentation 来请求启动,ActivityThread 通过 Instrumentation 来创建 Activity 和回调 Activity 的生命周期。
  • ActivityThread:每个应用程序只有一个唯一实例,负责对 Activity 创建的管理。ActivityThread 的内部类 ApplicationThread 只负责 App 进程和 AMS 进程的通信,将来自 AMS 的事务交给 ActivityThread 处理。
  • AMS,全称 ActivityManagerService,系统级服务,负责管理四大组件。

根 Activity 的启动

根 Activity 就是我们点击手机桌面图标的时候,应用程序启动的第一个 Activity。启动根 Activity 的流程其实和启动普通 Activity 的流程类似,只是启动根 Activity 时需要新建 App 进程。总体流程如下图:

未命名文件.jpg

其中涉及了四个进程,Launcher 进程、AMS 进程、App 进程以及 Zygote 进程。整体步骤是:

  1. Launcher 进程访问 AMS 进程请求启动目标 Activity,采用的跨进程技术是 AIDL;
  2. AMS 进程访问 Zygote 进程请求启动一个新进程,采用的跨进程技术是 Socket;
  3. Zygote 进程调用 fork 函数创建 App 进程;
  4. App 进程创建结束后,App 进程访问 AMS 进程进行通知,采用的跨进程技术是 AIDL;
  5. AMS 进程收到来自 App 进程的通知后,将启动 Activity 的操作封装成事务(ClientTransaction,后面会介绍),并将封装好的事务发送给 App 进程;
  6. App 进程接收到来自 AMS 的事务后,根据事务创建目标 Activity,并回调目标 Activity 的生命周期。

源码

根 Activity 的启动流程包含了普通 Activity 的启动流程,所以我们只需要分析根 Activity 的启动流程。

整个启动流程可以分为三个阶段:

  1. Activity 请求 AMS
  2. AMS 处理请求
  3. App 进程创建目标 Activity

Activity 请求 AMS

Android 的桌面其实是一个叫做 Launcher 的 App,当用户点击桌面上的应用图标时,就会调用到 startActivitySafely 函数。

// packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
public boolean startActivitySafely(View v, Intent intent, ItemInfo item)
{
    ......
    // 添加 Intent.FLAG_ACTIVITY_NEW_TASK
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Utilities.ATLEAST_MARSHMALLOW 
            && (item instanceof ShortcutInfo) 
            && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT 
            || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) 
            && !((ShortcutInfo) item).isPromise())
    {
        startShortcutIntentSafely(intent, optsBundle, item);
    }
    else if (user == null || user.equals(Process.myUserHandle()))
    {
        startActivity(intent, optsBundle);
    }
    else
    {
        LauncherAppsCompat.getInstance(this).startActivityForProfile(
                intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
    }
    return true;
    ......
}
复制代码

最终会调用到 Activity.java 的 startActivity 函数。

// frameworks/base/core/java/android/app/Activity.java
public void startActivity(Intent intent)
{
    this.startActivity(intent, null);
}

public void startActivity(Intent intent, Bundle options)
{
    if (options != null)
    {
        startActivityForResult(intent, -1, options);
    }
    else
    {
        startActivityForResult(intent, -1);
    }
}

public void startActivityForResult(Intent intent, int requestCode)
{
    startActivityForResult(intent, requestCode, null);
}

public void startActivityForResult(Intent intent, int requestCode, Bundle options)
{
    // mParent 是指 ActivityGroup,现在已经采用 Fragment 代替,mParent 一直为空
    if (mParent == null)
    {
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
    }
    ......
}

// Instrumentation.java
public ActivityResult execStartActivity(
        Context who, IBinder contextThread,
        IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options
){
    ......
    int result = ActivityManager.getService()
        .startActivity(whoThread, who.getBasePackageName(), intent,
                intent.resolveTypeIfNeeded(who.getContentResolver()),
                token, target != null ? target.mEmbeddedID : null,
                requestCode, 0, null, options);
    ......
}
复制代码

ActivityManager.getService() 是 AIDL 调用,获取到的是 binder 驱动中 AMS 实例的引用。简单来说就是调用到 AMS 的 startActivity 函数。

AMS 处理请求

在讲解 AMS 部分的代码之前,先介绍几个会在 AMS 代码中出现的关键类:

  • ProcessRecord:描述进程相关信息的类,一个 ProcessRecord 对应着一个进程。
  • ActivityRecord:描述 Activity 相关信息的类,一个 ActivityRecord 对应着一个 Activity。
  • TaskRecord:描述 Task 相关信息的类,一个 TaskRecord 对应着一个 Task,内部维护一个 ArrayList<ActivityRecord> 用来记录 Task 中保存的 ActivityRecord。
  • ActivityStack:用于管理 Task(TaskRecord)的类,内部维护了一个 ArrayList<TaskRecord>,用来记录 Task。
  • ActivityStackSupervisor:用于管理 ActivityStack 的类。ActivityStack 由 ActivityStackSupervisor 进行创建并管理。这个类在 AMS 初始化的时候就会创建。
  • ClientTransaction:一种容器,用于保存一系列需要发送给 App 进程的消息。这些消息包括 callbacks 和最终的生命周期状态。
  • ClientTransactionItem:一种发送给 App 进程的回调消息格式,可以对其进行调度和执行。
  • LaunchActivityItem:继承自 ClientTransactionItem,一种用于回调 App 进程启动一个 Activity 的消息格式。
  • ActivityLifecycleItem:继承自 ClientTransactionItem,一种用于回调 App 进程所请求启动的 Activity 应达到的生命周期状态的消息格式。
// ActivityManagerService.java
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());
}

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 /*validateIncomingUser*/);
}

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
){
    ......
    // mActivityStartController.obtainStarter 获取到的是 ActivityStarter
    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) // mRequest.mayWait = true
            .execute();
}
复制代码

AMS 中关于启动 Activity 的逻辑都由 ActivityStarter 来执行。

// ActivityStarter.java
int execute()
{
    ......
    // 此时 mRequest.mayWait = true,if 命中
    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);
    }
    ......
}

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 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);
    ......
}

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
){
    ......
    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);
    ......
}

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
){
    // 获取描述 Launcher 进程的 ProcessRecord 对象
    ProcessRecord callerApp = null;
    if (caller != null)
    {
        callerApp = mService.getRecordForAppLocked(caller);
        ......
    }
    ......
    // 创建目标 Activity 的 ActivityRecord 对象,记录目标 Activity 的相关信息
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
            callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
            resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
            mSupervisor, checkedOptions, sourceRecord);
    ......
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
            true /* doResume */, checkedOptions, inTask, outActivity);
}

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);
    ......
}

private int startActivityUnchecked(
        final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, 
        TaskRecord inTask, ActivityRecord[] outActivity
){
    // 初始化状态。此时 mStartActivity = 目标 Activity,mDoResume = doResume = true
    setInitialState(r, options, inTask, doResume, startFlags, 
            sourceRecord, voiceSession, voiceInteractor);
    ......
    mIntent.setFlags(mLaunchFlags);
    // getReusableIntentActivity --> 根据启动模式判断是否要重用已经存在的目标 Activity 实例。
    // 如果判断为重用,返回描述对应实例的 ActivityRecord 对象;否则返回 null
    ActivityRecord reusedActivity = getReusableIntentActivity();
    ......
    // 如果需要重用已经存在的目标 Activity 实例。显然此时 if 不命中
    if (reusedActivity != null)
    {
        ......
    }
    ......

    /** 
     * 源码注释:
     * 如果本次流程的目标 Activity 与当前位于前台 Task 底部(栈顶)的 Activity 相同,
     * 那么我们需要检查它是否应该只启动一次。
     * (检查本次流程是否应该再次启动目标 Activity)
     */
    
    // 获取当前所有可能会获取焦点的 Task(Task 堆叠)
    final ActivityStack topStack = mSupervisor.mFocusedStack;
    // 获取描述当前位于前台 Task 底部(栈顶)的 Activity 的 ActivityRecord 对象
    final ActivityRecord topFocused = topStack.getTopActivity();
    final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);

    // 如果本次流程不应该再次启动目标 Activity,则 dontStart = true;
    // 否则 dontStart = false
    final boolean dontStart = top != null && mStartActivity.resultTo == null
            && top.realActivity.equals(mStartActivity.realActivity)
            && top.userId == mStartActivity.userId
            && top.app != null && top.app.thread != null
            && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
            || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
            
    // 显然此时 if 不命中
    if (dontStart)
    {
        ......
    }

    boolean newTask = false;
    ......
    int result = START_SUCCESS;
    ......
    // 如果本次流程满足切换 Task 的条件,且添加了 Intent.FLAG_ACTIVITY_NEW_TASK
    // 此时 if 命中
    if (mStartActivity.resultTo == null && mInTask == null 
            && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0)
    {
        newTask = true;
        // 切换 Task。如果目标 Task 没有创建,则创建目标 Task。
        // 此时 mTargetStack = 目标 Task
        result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
    }
    ......
    // 将目标 Task 设置为前台,并播放目标 Activity 的启动动画(如果有的话)
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, 
            mKeepCurTransition, mOptions);

    // 此时 mDoResume = true,if 命中
    if (mDoResume)
    {
        // 获取描述当前状态为可见的 Activity 的 ActivityRecord 对象
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        // 判断当前位于前台 Task 底部(栈顶)的 Activity 是否是目标 Activity
        // 显然此时 mStartActivity = topTaskActivity。if 不命中,执行 else
        if (!mTargetStack.isFocusable()
                || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                && mStartActivity != topTaskActivity))
        {
            ......
        }
        else
        {
            ......
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, 
                    mStartActivity, mOptions);
        }
    }
    ......
}
复制代码

所有关于 Activity 启动模式的处理都是在 ActivityStarter 的 startActivityUnchecked 函数中进行的。

startActivityUnchecked 函数中的细节很多,其中有些对于 Activity 启动模式的重点判断,我没有介绍其中的细节,因为那与当前正在分析的流程无关。

如果对于 Activity 启动模式很有兴趣,一定要将那些细节部分仔细看一下。

// ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, 
        ActivityOptions targetOptions
){
    ......
    // 如果目标 Task 已经处于前台
    if (targetStack != null && isFocusedStack(targetStack))
    {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    ......
}

// ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options)
{
    ......
    boolean result = false;
    ......
    result = resumeTopActivityInnerLocked(prev, options);
    ......
    return result;
}

private boolean resumeTopActivityInnerLocked(
        ActivityRecord prev, // 目标 Activity
        ActivityOptions options
){
    ......
    // 获取描述当前状态为可见的 Activity 的 ActivityRecord 对象
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    ......
    // 此时 prev = next,if 不命中
    if (prev != null && prev != next)
    {
        ......
    }
    ......
    // 此时目标 App 进程还没创建,next.app = next.app.thread = null,执行 else
    if (next.app != null && next.app.thread != null)
    {
        ......
        realStartActivityLocked(r, app, andResume, checkConfig);
        return;
    }
    else
    {
        ......
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    ......
    return true;
}
复制代码

因为分析的是根 Activity 的启动流程,所以此时的目标 App 进程是还没有启动的。

如果是普通 Activity 的启动流程,此时就会命中 if,直接调用到 realStartActivityLocked 函数(当目标 App 进程创建之后,也会调用该函数,所以该函数后面也会分析到)。

根 Activity 的启动流程就是比普通 Activity 的启动流程多了一个创建进程的操作。

AMS 请求 Zygote 创建 App 进程

// ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig)
{
    // 查找系统中所有 App 进程的 ProcessRecord 记录,查看目标 App 进程是否已经启动
    // 此时目标 App 进程还未启动,app = null
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
    ......
    // app = null,if 不命中
    if (app != null && app.thread != null)
    {
        ......
    }
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

// ActivityManagerService.java
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 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}

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);
    ......
    return success ? app : null;
}

private final boolean startProcessLocked(ProcessRecord app,
        String hostingType, String hostingNameStr, String abiOverride
){
    return startProcessLocked(app, hostingType, hostingNameStr,
            false /* disableHiddenApiChecks */, abiOverride);
}

private final boolean startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride
){
    ......
    return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
            runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
            startTime);
    ......
}

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
){
    ......
    // mConstants.FLAG_PROCESS_START_ASYNC 默认值为 true,if 命中
    if (mConstants.FLAG_PROCESS_START_ASYNC)
    {
        ......
        final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
                app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
                requiredAbi, instructionSet, invokeWith, app.startTime);
        ......
    }
    ......
}

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
){
    ......
    // 显然执行 else
    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});
    }
    ......
    return startResult;
}

// Process.java
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);
}

// ZygoteProcess.java
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 /* startChildZygote */,
            zygoteArgs);
    ......
}

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
){
    ......
    return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}

private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, ArrayList<String> args
){
    try
    {
        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();

        // 阻塞线程直至 Zygote 进程返回
        result.pid = inputStream.readInt();
        result.usingWrapper = inputStream.readBoolean();

        return result;
    }
    catch (IOException ex)
    {
        zygoteState.close();
    }
}
复制代码

之后进程的创建就到了 Zygote 进程了,创建进程的具体代码就不再分析了,有兴趣的可以自己跟进。

可以看到 AMS 进程和 Zygote 进程之间是通过 Socket 进行通信的。当 AMS 进程与 Zygote 进程通信时,AMS 进程会同步等待 Zygote 进程返回结果。

当目标 App 进程创建完成后,Zygote 进程通过 Socket 返回结果给 AMS;AMS 线程被唤醒,并返回结果给 Launcher 进程。该返回流程没有什么特别需要注意的细节,在这里我们就不分析了。

App 进程创建完成

当目标 App 进程创建完成后,就会进行初始化,调用到 ActivityThread 的 main 函数。

// ActivityThread.java
public static void main(String[] args)
{
    ......
    thread.attach(false, startSeq);
    ......
}

private void attach(boolean system, long startSeq)
{
    ......
    // AIDL 调用,调用到 AMS 的 attachApplication 函数
    final IActivityManager mgr = ActivityManager.getService();
    mgr.attachApplication(mAppThread, startSeq);
    ......
}

// ActivityManagerService.java
public final void attachApplication(IApplicationThread thread, long startSeq)
{
    ......
    attachApplicationLocked(thread, callingPid, callingUid, startSeq);
    ......
}

private final boolean attachApplicationLocked(
        IApplicationThread thread, // thread = 目标 App 进程的 ApplicationThread
        int pid, int callingUid, long startSeq
){
    ......
    // 当系统启动完成后,mProcessesReady = normalMode = true
    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
    ......
    if (normalMode)
    {
        if (mStackSupervisor.attachApplicationLocked(app))
        {
            didSomething = true;
        }
    }
    ......
}

// ActivityStackSupervisor.java
boolean attachApplicationLocked(ProcessRecord app)
{
    ......
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx)
    {
        final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
        // 遍历系统中所有的 Task
        for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx)
        {
            final ActivityStack stack = display.getChildAt(stackNdx);
            // 如果当前 Task 没有处于前台,则跳过本次循环
            if (!isFocusedStack(stack))
            {
                continue;
            }
            // 给 mTmpActivityList 赋值,所有状态为可见的 Activity
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
            // 获取描述当前状态为可见的 Activity 的 ActivityRecord 对象
            final ActivityRecord top = stack.topRunningActivityLocked();
            final int size = mTmpActivityList.size();
            // 遍历 mTmpActivityList
            for (int i = 0; i < size; i++)
            {
                final ActivityRecord activity = mTmpActivityList.get(i);
                // 如果当前遍历到的 Activity 属于目标 App 进程
                if (activity.app == null 
                        && app.uid == activity.info.applicationInfo.uid
                        && processName.equals(activity.processName))
                {
                    // 执行 realStartActivityLocked 函数
                    if (realStartActivityLocked(activity, app,
                            top == activity /* andResume */, true /* checkConfig */))
                    {
                        didSomething = true;
                    }
                }
            }
        }
    }
    ......
    return didSomething;
}
复制代码

最终,当 App 进程创建完成后,会遍历 AMS 中所有状态为可见的 Activity;如果 Activity 属于目标 App 进程,就会调用 realStartActivityLocked 函数。

// ActivityStackSupervisor.java
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, // 此时 top = activity,andResume = true
        boolean checkConfig)
{
    ......
    // 创建回调消息的容器 ClientTransaction
    final ClientTransaction clientTransaction = 
            ClientTransaction.obtain(app.thread, r.appToken);
    // 添加回调消息 LaunchActivityItem(启动一个 Activity)
    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;
    // andResume = true,if 命中
    if (andResume)
    {
        // 创建回调消息 ResumeActivityItem(回调的生命周期状态为 Resume)
        lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
    }
    else
    {
        lifecycleItem = PauseActivityItem.obtain();
    }
    // 添加回调消息 ResumeActivityItem
    clientTransaction.setLifecycleStateRequest(lifecycleItem);

    // 将 ClientTransaction 发送给 App 进程
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    ......
}

// ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction)
{
    ......
    transaction.schedule();
    ......
}

// ClientTransaction.java
public void schedule()
{
    // mClient = 目标 App 进程的 ApplicationThread
    // AIDL 调用,调用到 ApplicationThread 的 scheduleTransaction 函数
    mClient.scheduleTransaction(this);
}
复制代码

经过 AIDL 调用,就会返回目标 App 进程执行 scheduleTransaction 函数。

App 进程创建目标 Activity

// ActivityThread$ApplicationThread.java
public void scheduleTransaction(ClientTransaction transaction)
{
    ActivityThread.this.scheduleTransaction(transaction);
}

// ClientTransactionHandler.java(ActivityThread 继承自 ClientTransactionHandler)
void scheduleTransaction(ClientTransaction transaction)
{
    // 预处理
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

abstract void sendMessage(int what, Object obj);

// ActivityThread.java
@Override
void sendMessage(int what, Object obj)
{
    sendMessage(what, obj, 0, 0, false);
}

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async)
{
    ......
    // 创建 message
    Message msg = Message.obtain();
    msg.what = what; // H.EXECUTE_TRANSACTION
    msg.obj = obj; // ClientTransaction
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async)
    {
        msg.setAsynchronous(true);
    }
    // mH 是主线程 handler,切换线程执行 ClientTransaction
    mH.sendMessage(msg);
}

// ActivityThread$H.java
@Override
public void handleMessage(Message msg)
{
    ......
    switch (msg.what)
    {
        ......
        case EXECUTE_TRANSACTION:
            final ClientTransaction transaction = (ClientTransaction) msg.obj;
            // 调用事务池对 ClientTransaction 进行处理
            mTransactionExecutor.execute(transaction);
            if (isSystem())
            {
                transaction.recycle();
            }
            break;
        ......
    }
    ......
}

// TransactionExecutor.java
public void execute(ClientTransaction transaction)
{
    final IBinder token = transaction.getActivityToken();
    // 执行回调消息 LaunchActivityItem
    executeCallbacks(transaction);
    // 执行回调消息 ResumeActivityItem
    executeLifecycleState(transaction);
    mPendingActions.clear();
}
复制代码

在 TransactionExecutor 的 execute 函数中会分别执行回调消息 LaunchActivityItem 和 ResumeActivityItem。

这是两个不同的流程,需要分开进行分析。

执行 LaunchActivityItem

// TransactionExecutor.java
public void executeCallbacks(ClientTransaction transaction)
{
    ......
    // 获取 ClientTransaction 中 callbacks 的数量
    final int size = callbacks.size();
    // 遍历 ClientTransaction 中的所有 callbacks
    for (int i = 0; i < size; ++i)
    {
        final ClientTransactionItem item = callbacks.get(i);
        ......
        item.execute(mTransactionHandler, token, mPendingActions);
        ......
    }
}

// LaunchActivityItem.java
public void execute(ClientTransactionHandler client, // client = ActivityThread
        IBinder token,
        PendingTransactionActions pendingActions)
{
    // 创建 ActivityClientRecord 对象
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, 
            mPersistentState, mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client);
    // 调用 ActivityThread 的 handleLaunchActivity 函数
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}

// ActivityThread.java
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent)
{
    ......
    final Activity a = performLaunchActivity(r, customIntent);
    ......
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent)
{
    // 获取 ActivityInfo,用户存储代码、AndroidManifes 信息
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null)
    {
        // 获取 Apk 描述类
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }

    // 获取 Activity 的包名类型信息
    ComponentName component = r.intent.getComponent();
    if (component == null)
    {
        component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }
    ......
    // 创建 Activity 的 context
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    ......
    java.lang.ClassLoader cl = appContext.getClassLoader();
    // 通过 Instrumentation 来创建活动(使用反射进行创建)
    activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);
    ......
    // 根据包名创建 Application,如果已经创建则不会重复创建
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    ......
    if (activity != null)
    {
        ......
        // 为 Activity 添加 Window
        Window window = null;
        if (r.mPendingRemoveWindow != null && r.mPreserveWindow)
        {
            window = r.mPendingRemoveWindow;
            r.mPendingRemoveWindow = null;
            r.mPendingRemoveWindowManager = null;
        }
        ......
        // 执行 Activity 的 attach 函数进行初始化
        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);
        ......
        // 执行 else
        if (r.isPersistable())
        {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        }
        else
        {
            // 通过 Instrumentation 回调 Activity 的 onCreate 函数
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        ......
    }
    ......
    return activity;
}

// Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle)
{
    ......
    activity.performCreate(icicle);
    ......
}

// Activity.java
final void performCreate(Bundle icicle)
{
    performCreate(icicle, null);
}

final void performCreate(Bundle icicle, PersistableBundle persistentState)
{
    ......
    // 执行 else
    if (persistentState != null)
    {
        onCreate(icicle, persistentState);
    }
    else
    {
        // 回调生命周期中的 onCreate 函数
        onCreate(icicle);
    }
    ......
}
复制代码

执行 LaunchActivityItem 后,就会创建目标 Activity 的实例对象,并回调目标 Activity 生命周期中的 onCreate 函数。

执行 ResumeActivityItem

// TransactionExecutor.java
private void executeLifecycleState(ClientTransaction transaction)
{
    ......
    // lifecycleItem = ResumeActivityItem
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    ......
}

// ResumeActivityItem.java
public void execute(ClientTransactionHandler client, // client = ActivityThread
        IBinder token,
        PendingTransactionActions pendingActions)
{
    ......
    // 调用 ActivityThread 的 handleResumeActivity 函数
    client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
            "RESUME_ACTIVITY");
    ......
}

// ActivityThread.java
public void handleResumeActivity(IBinder token, boolean finalStateRequest, 
        boolean isForward, String reason)
{
    ......
    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
    ......
}

public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
        String reason)
{
    final ActivityClientRecord r = mActivities.get(token);
    ......
    r.activity.performResume(r.startsNotResumed, reason);
    ......
    return r;
}

// Activity.java
final void performResume(boolean followedByPause, String reason)
{
    // 判断是否需要执行 Restart 流程
    performRestart(true /* start */, reason);
    ......
    // 通过 Instrumentation 回调 Activity 的 onResume 函数
    mInstrumentation.callActivityOnResume(this);
    ......
}

// Instrumentation.java
public void callActivityOnResume(Activity activity)
{
    ......
    // 回调生命周期中的 onResume 函数
    activity.onResume();
    ......
}
复制代码

执行 ResumeActivityItem 后,就会回调目标 Activity 生命周期中的 onResume 函数。

总结

Activity启动流程.jpg

本篇文章分析了根 Activity 的完整启动流程,将其中对于我们开发者而言比较有意义的部分代码进行了分析。

了解 Activity 启动流程,对于我们理解 Activity 启动模式和 Activity 生命周期有着很大的帮助。但是源码还是非常庞大的,没办法面面俱到,希望读者还是能参照本篇文章尝试自己去阅读源码,加深理解。

参考

Android之Activity启动流程详解(基于api28)

AMS startActivity()

文章分类
Android
文章标签