Android9.0 ActivityManagerService源码之启动Activity中篇

861 阅读36分钟

一、引言

  在文章启动Activity开篇中对存储Activity的基本数据结构类、launchMode、亲和性以及分析源码过程中所涉及到的部分Flag简单的做了一个介绍以帮助后续对源码的理解。因为一下子将所有东西都写完,可能会导致篇幅特别特别长,所以该篇文章只解析到框架通过Binder的方式调用到上层应用执行Activity的生命周期的地方。下一篇文章会对Activity的生命周期源码进行解析。

  在Android开发过程中,我们可以通过Context引用、Activity引用、Service引用以及Application引用来启动一个Activity,而归根结底来说是因为Activity、Service以及Application都间接的继承了Context这个抽象类。关于Context的详细讲解可以参考这篇博客 www.jianshu.com/p/94e0f9ab3… 。因此我们可以在任何有Context实例引用的地方启动一个Activity。

二、正文

  接下来我们就以Activity调用startActivity方法为起点开始Activity启动流程解析。

1、Activity起点

  这里面启动Activity的代码非常简单,不论是调用startActivity启动页面还是通过startActivityForResult方法启动一个页面,最后都会调用到startActivityForResult方法中,并在startActivityForResult方法中通过调用Instrumentation的execStartActivity方法来调用到AMS中启动Activity,所以这里就简单的看一下startActivityForResult中的代码。

  在该方法中首先会去判断当前Activity的parent是否为null,这里的parent会在调用Activity中attach的时候被赋值,简单来说就是当前Activity的父Activity,比如在TabActivity这个组件中就存在子Activity和父Activity的说法。不过这里走的流程是普通Activity的启动流程,所以可以先假设mParent为null,那么就会去调用到Instrumentation中,这里一定要理解传入到Instrumentation中变量的含义,在后续AMS源码解析过程中非常重要。

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        //最终调用到Instrumentation实例中
        //在Instrumentation中有对各个参数进行讲解
         Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            mStartedActivity = true;    
        }
        cancelInputsAndStartExitTransition(options);
    } else {
        .......................
    }
}

  为了能够和普通startActivity方法启动页面形成对比,我们看一下在Context的实现类ContextImpl类(如果不是Activity实例对象都会调用该类中的方法)中是如何启动一个页面的。

 public void startActivity(Intent intent, Bundle options) {
    //如果是在系统中调用该方法会打印一条警告
    //一般在系统中启动Activity需要指明用户id
    warnIfCallingFromSystemProcess();
    //通过该类启动Activity,那么该Activity可能会新建任务栈存储Activity实例,所以需要在Intent中加上FLAG_ACTIVITY_NEW_TASK
    final int targetSdkVersion = getApplicationInfo().targetSdkVersion;
    if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
            && (targetSdkVersion < Build.VERSION_CODES.N
                    || targetSdkVersion >= Build.VERSION_CODES.P)
            && (options == null
                    || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
        throw new AndroidRuntimeException(
                "Calling startActivity() from outside of an Activity "
                        + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                        + " Is this really what you want?");
    }
    //在该方法中启动一个界面会发现并没有token、Activity等实例
    mMainThread.getInstrumentation().execStartActivity(
            getOuterContext(), mMainThread.getApplicationThread(), null,
            (Activity) null, intent, -1, options);
}

2、中转点Instrumentation

  对于Instrumentation介绍网上有很多,可以去百度一下。它的作用不仅仅只是通过Binder的方式调用到AMS中来启动一个页面这么简单,我们还可以通过该类进行单元测试,也可以通过对该类进行hook来实现热修复等操作。因为这里只是对为了解析Activity启动流程,所以只是路过一下而已。

/**
* who:当前Activity实例对象
* contextThread:当前Activity所在应用进程的binder对象,也就是能够和框架交互的Binder对象
* mToken:用于标识是哪一个Activity正在启动Activity,在ContextImpl类中该值就为null,可用于返回结果
* target:返回结果给该界面,在ContextImpl类中该值就为null
* intent:要启动Activity的Intent
* requestCode:如果为-1则表示没有返回结果
* options:额外的参数,一般也为null
**/
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    ........................
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    ................................
    try {
        ...................
        int result = ActivityManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        //根据不同的返回结果抛出对应的异常
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

  Instrumentation中会直接通过调用ActivityManager中的getService方法获取到能够和AMS通信的Binder对象,也就是AMS的实例对象。然后通过该Binder对象将启动方Binder等基本信息以及要启动的Activity Intent信息发送给AMS进行处理。

3、AMS代理管家ActivityManager

  在ActivityManager类中是通过一个单例的方式来生成和AMS相关的Bidner对象。逻辑很简单,可以简单的看一下其中的源码部分。

//这个方法很简单,直接调用的IActivityManagerSingleton这个实例对象中的get方法
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}
//最后生成的是一个Singleton类型的实例对象,所以还需要继续看一下Singleton类中的实现逻辑
private static final Singleton<IActivityManager> IActivityManagerSingleton =
    new Singleton<IActivityManager>() {
        @Override
        protected IActivityManager create() {
            final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
            final IActivityManager am = IActivityManager.Stub.asInterface(b);
            return am;
    }
};
//很明显该类是通过单例的方式进行实现的,并且在get方法中会调用抽象方法create方法,也就是IActivityManagerSingleton对象中的create方法。
public abstract class Singleton<T> {
    private T mInstance;
    protected abstract T create();
    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

4、ActivityManagerService

  其实在AMS中也没有做什么事情,最终也只是通过ActivityStartController类中的obtainStarter方法通过工厂模式生成了一个ActivityStarter实例对象,并将从Instrumentation类中传递过来的参数传递到ActivityStarter中。因为很简单所以就简单的看一下。

 //在Instrumentation中通过调用AMS中的startActivity方法启动页面最终也会调用到该方法中
 //在讲解Instrumentation类的时候有对这些参数进行解释,所以这里就不再重复讲解了
 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) {
    //判断启动Activity应用是否允许启动应用,如果不允许则直接抛出异常
    enforceNotIsolatedCaller("startActivity");
    //获取当前的userID,注意是userID不是uid
    userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    //构造ActivityStarter实例对象并将参数传递给该对象实例,最后调用该对象的execute方法正式开始Activity启动流程
    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();
}

5、ActivityStarter

  在该类中会对Activity是否存在、是否有权限启动该Activity、是否能够重用任务栈或者Activity以及新建任务栈等情况做判断,并根据不同的处理结果做出不同的情况处理。所以总的来说不算特别复杂。通过普通startActivity的方式启动一个页面在ActivityStarter中都会调用到startActivityMaywait方法,所以就直接进入到该方法。

5.1 startActivityMayWait

  这个方法中代码量其实还好不是很多,所做的事情也不是很多,可以分为如下几个部分:

(1)判断要启动的Activity是否是instant app,如果是该类型的应用则不能直接使用Component的方式启动,所以将设置的Component置为null。至于什么是instant app大家可以百度一下,有点类似于微信小程序;

(2)根据传入的Intent从PackageManagerService中查找对应的ResolveInfo;

(3)根据查找到的ResolveInfo以及要启动Activity获取对应的ActivityInfo,并为当前Intent设置Component;

(4)根据查找到的ActivityInfo判断其对应的进程是否是hight-weight进程;至于什么是hight-weight进程,我也不是特别清楚,只知道该应用进程的生命周期和普通应用进程生命周期不一样;因为这里不涉及到,所以直接跳过;

(5)继续调用startActivity方法,然后对其返回结果进行处理。

  因为篇幅原因这里只展示部分重要的代码,按着上面的执行流程,这一块儿的代码是能够看明白的。

/**
* caller:哪个应用进程调用的AMS
* callingUid:调用AMS的应用id
* callingPackage:调用AMS的应用包名
* intent:要启动Activity的intent信息
* resolvedType:要启动Activity的能够处理的mimeType,具体可以百度一下
* voice:和语音助手相关这里不涉及
* resultTo:将结果返回给哪一个Activity
* resultWho:结果返回给对应Activity的包名
* requestCode:如果该值大于0就会返回结果给上一个Activity
* startFlags:当前调用解析的调用流程为0
* userId:当前处于哪一个用户下
* inTask:指定栈启动Activity,当前解析流程为null
**/
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) {
    //记录当前的intent,后面可能会对Intent进行修改
    final Intent ephemeralIntent = new Intent(intent);
    intent = new Intent(intent);
    //处理instant app
    .............................
    //从PackageManagerService中根据intent解析出对应的ResolveInfo,在PMS可能会找到多个满足条件的ResolveInfo,但是会选择其中最适合的一个作为返回结果
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
            0 /* matchFlags */,
                    computeResolveFilterUid(
                            callingUid, realCallingUid, mRequest.filterCallingUid));
    //这是一种比较特殊的场景,其中的注释是说当前场景是manager profile,关于manager profile介绍可以参考下面的连接
    //https://www.w3cschool.cn/android_training_course/android_training_course-t3xv27in.html
    ....................
    //从获取的ResolveInfo中获取对应的ActivityInfo,主要是AndroidManifest文件中配置的Activity基本信息,比如权限、lanchMode以及亲和性等
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    synchronized (mService) {
        //获取当前可以和用户交互的ActivityStack
        final ActivityStack stack = mSupervisor.mFocusedStack;
        //globalConfig这个值在调用startActivity方法启动页面不会赋值也就是为null
        stack.mConfigWillChange = globalConfig != null
                && mService.getGlobalConfiguration().diff(globalConfig) != 0;
        final long origId = Binder.clearCallingIdentity();
        //判断要启动的Activity对应的进程是否是heavy-weight进程,如果是并且当前还存在其他heavy-weight进程在运行并且和
        //当前的不一致,则会重新构造Intent并重新获取ResolveInfo和ActivityInfo
        .............................
        final ActivityRecord[] outRecord = new ActivityRecord[1];
        //继续调用startActivity方法
        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);
        Binder.restoreCallingIdentity(origId);
        //对返回结果进行处理
        ...........................
        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
        return res;
    }
}

  在该方法中主要目的就是正确获取到要启动Activity对应的ResolveInfo和ActivityInfo信息。然后继续调用重载方法startActivity,在该方法中并没有做什么特别的事情,只是判断了一下reason是否为null,如果为null则会直接抛出异常,如果不为null则会记录当前启动Activity的reason以及启动时间,然后继续调用另一个startActivity方法。因为代码很简单所以直接跳转到下一个startActivity方法。

5.2 startActivity

  该方法主要是对是否能够启动Activity做判断,比如是否有权限启动要启动的Activity,是否对要启动的Activity进行拦截等,并根据实际场景对ResolveInfo以及ActivityInfo做替换。接下来多代码警告,因为篇幅原因所以删除了其中的注释、log以及当前不涉及的代码部分等。

 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) {
    //标识是否需要结束启动Activity流程
    int err = ActivityManager.START_SUCCESS;
    //判断启动Activity的应用进程是否存在,如果不存在则不允许启动Activity
    ProcessRecord callerApp = null;
    if (caller != null) {
        //从进程列表中查找对应的应用进程
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
    //获取要启动Activity所在的用户id
    final int userId = aInfo != null && aInfo.applicationInfo != null
            ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
    ......................
    //根据上一个Activity的binder对象从任务栈中查找能够接收接收返回结果的Activity
    ActivityRecord sourceRecord = null;
    ActivityRecord resultRecord = null;
    if (resultTo != null) {
        sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
        .................
        if (sourceRecord != null) {
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }
    //获取intent中的flags
    final int launchFlags = intent.getFlags();
    //该flag在上一篇文章有讲解到,也就是结果透传,也就是说如果当前Intent中包含该flag
    //说明启动Activity的返回结果会返回到上上个Activity中,并且将resultRecord替换为上上个界面的ActivityRecord对象
    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
        if (requestCode >= 0) {
            SafeActivityOptions.abort(options);
            return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
        }
        resultRecord = sourceRecord.resultTo;
        if (resultRecord != null && !resultRecord.isInStackLocked()) {
            resultRecord = null;
        }
        resultWho = sourceRecord.resultWho;
        requestCode = sourceRecord.requestCode;
        sourceRecord.resultTo = null;
        if (resultRecord != null) {
            resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
        }
        if (sourceRecord.launchedFromUid == callingUid) {
            callingPackage = sourceRecord.launchedFromPackage;
        }
    }
    //Intent中的Component会在获取ActivityInfo的过程中构造,如果不存在则说明该Activity不存在
    if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
        err = ActivityManager.START_INTENT_NOT_RESOLVED;
    }
    //要启动的Activity不存在
    if (err == ActivityManager.START_SUCCESS && aInfo == null) {
        err = ActivityManager.START_CLASS_NOT_FOUND;
    }
    //语音会话相关的代码这里暂时忽略
    .....................
    //获取接收返回结果ActivityI对应的ActivityStack
    final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
    //如果不能启动Activity则发送取消结果,并停止执行后续启动Activity操作
    if (err != START_SUCCESS) {
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(
                    -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
        }
        SafeActivityOptions.abort(options);
        return err;
    }
    //判断是否允许启动Activity,其中包括权限检测以及是否拦截等
    .............................
    if (abort) {
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
                    RESULT_CANCELED, null);
        }
        ActivityOptions.abort(checkedOptions);
        return START_ABORTED;
    }
    //这一块儿大致意思呢就是,如果在启动某一个应用组件之前需要权限检测,
    //那么我们首先会启动一个权限检测Activity,在权限检测完之后立即启动该Activity
    //下面代码就构造了一个新的Intent用于启动权限检测界面并重新获取了ResolveInfo和ActivityInfo
    if (mService.mPermissionReviewRequired && aInfo != null) {
        if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                aInfo.packageName, userId)) {
            IIntentSender target = mService.getIntentSenderLocked(
                    ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
                    callingUid, userId, null, null, 0, new Intent[]{intent},
                    new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
                            | PendingIntent.FLAG_ONE_SHOT, null);
            final int flags = intent.getFlags();
            Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
            newIntent.setFlags(flags
                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
            newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
            if (resultRecord != null) {
                newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
            }
            intent = newIntent;
            resolvedType = null;
            callingUid = realCallingUid;
            callingPid = realCallingPid;
            rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
                    computeResolveFilterUid(
                            callingUid, realCallingUid, mRequest.filterCallingUid));
            aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
                    null /*profilerInfo*/);
        }
    }
    //如果我们存在instant app,那么我们会启动该instant app,所以这里需要对Intent以及ActivityInfo做替换
    if (rInfo != null && rInfo.auxiliaryInfo != null) {
        intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
                callingPackage, verificationBundle, resolvedType, userId);
        resolvedType = null;
        callingUid = realCallingUid;
        callingPid = realCallingPid;
        aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
    }
    //将Activity信息构造为ActivityRecord进行存储,后续会将该ActivityRecord对象存储到对应的任务栈中
    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;
    }
    //应用使用时间记录timer
    if (r.appTimeTracker == null && sourceRecord != null) {
        r.appTimeTracker = sourceRecord.appTimeTracker;
    }
    .................
    mController.doPendingActivityLaunches(false);
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
            true /* doResume */, checkedOptions, inTask, outActivity);
}

  这一块儿的代码看着虽然有那么一点点长,不过仔细划分一下然后将自己走的流程涉及不到的逻辑部分过滤掉其实还是很简单的。主要就是做了下面几个事情:

(1)如果要启动Activity需要结果返回则根据传入的binder对象在stack中查找接收返回结果的ActivityRecord对象;然后判断是否需要结果透传,如果需要则将更新接收返回结果的ActivityRecord;

(2)判断Activity是否能够启动成功;如果不能则终止后续流程执行,并返回cancel结果给上一个界面;

(3)判断在启动应用组件前是否需要权限检测如果需要则重新构造Intent,并首先启动权限检测界面并在检测完之后立即启动要启动的界面;

(4)构造ActivityRecord对象并继续调用另一个startActivity方法;

  接着继续调用该类中的另一个startActivity方法,该方法也只是一个中转作用,最后会调用到startActivityUnChecked方法中,所以不多BB直接转到该方法中。

5.2 startActivityUnchecked相关方法

  看该方法大家一定要摆正姿势了,它涉及了我们平时开发过程中的LaunchMode以及Intent中的Flags值等,并根据这两个值来判断是否能够重用任务栈或者任务栈中存在的Activity。并将存放要启动Activity任务栈和ActivityStack移到前台来。如果能够把该方法理解了,那么对在应用层开发使用LaunchMode以及IntentFlags的理解大有裨益。首先该方法可以大致分为如下几个部分:

(1)将要启动Activity基本信息初始化为当前ActivityStarter成员变量值,包括LaunchMode、要启动Activity以及mSourceRecord等;

(2)判断是否需要为当前要启动Activity的LaunchFlags上新增FLAG_ACTIVITY_NEW_TASK标签;

(3)获取mSourceRecord的ActivityStack供后续使用;

(4)获取可重用栈中栈顶的ActivityRecord供后续使用;

(5)根据Intent中的flags以及Activity启动模式判断是否可以重用任务栈或者任务栈中的Activity;

(6)判断是否需要新建任务栈;

(7)处理启动Activity是否需要过渡动画;

(8)最后调用到ActivityStackSupervisor中;

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
    //初始化当前ActivityStarter中变量,包括当前要启动Activity、LaunchMode以及LaunchFlags等
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor);
    //根据情况判断是否需要新增FLAG_ACTIVITY_NEW_TASK标签到flags中,该方法后续有讲解
    computeLaunchingTaskFlags();
    //获取启动方Activity所在的ActivityStack,如果启动方不是Activity则mSourceStack=null
    computeSourceStack();
    //更新Intent中的flags值
    mIntent.setFlags(mLaunchFlags);
    //获取可重用栈中的栈顶ActivityRecord对象
    ActivityRecord reusedActivity = getReusableIntentActivity();
    ........................
    //判断是否存在可重用任务栈,如果存在则判断是否能够重用其中的Activity
    if (reusedActivity != null) {
        //不允许对固定应用的任务栈做清除任务栈等操作。该功能在设置-安全中开启,然后通过任务栏可固定应用
        if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),
                (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
            Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
            return START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }
        //LAUNCH_MULTIPLE模式对应于LaunchMode中的standard模式
        //当前为默认启动模式的时候是否需要重置任务栈并且清除已经存在Activity及其以上的所有Activity实例对象
        final boolean clearTopAndResetStandardLaunchMode =
                (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
                        == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
                && mLaunchMode == LAUNCH_MULTIPLE;
        if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {
            mStartActivity.setTask(reusedActivity.getTask());
        }
        //为TaskRecord设置根Activity
        if (reusedActivity.getTask().intent == null) {
            reusedActivity.getTask().setIntent(mStartActivity);
        }
        //如果当前LaunchMode是singleInstance或者singleTask
        //或者Intent中的flags带有FLAG_ACTIVITY_CLEAR_TOP,则会清除可复用Activity实例以上的所有Activity实例
        if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                || isDocumentLaunchesIntoExisting(mLaunchFlags)
                || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
            //获取可重用栈
            final TaskRecord task = reusedActivity.getTask();
            //在可重用栈中查找是否存在可复用的Activity,如果存在并且是默认的LaunchMode
            //则会清除该Activity及该Activity实例以上的所有Activity实例对象,并返回null;
            //如果可重用的Activity存在并且不是默认启动模式且没有finish,则返回该实例对象,不存在则直接返回null
            final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
                    mLaunchFlags);
            //上面clear操作可能会将reusedActivity移除栈
            if (reusedActivity.getTask() == null) {
                reusedActivity.setTask(task);
            }
            //判断是否找到了可复用的Activity,如果存在则执行该Activity中的onNewIntent方法
            if (top != null) {
                //如果top Activity是栈中的root Activity,则更新该TaskRecord的Intent,也就是根Activity的Intent
                if (top.frontOfTask) {
                    top.getTask().setIntent(mStartActivity);
                }
                //添加调用onNewIntent函数回调,会在执行Activity生命周期函数的时候执行
                deliverNewIntent(top);
            }
        }
        mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
        //将目标ActivityStack移到栈顶
        reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
        final ActivityRecord outResult =
                outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
        if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
            outActivity[0] = reusedActivity;
        }
        //不需要真正启动一个Activity,只需要让上一个处于top的Activity保持resume状态
        if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
            resumeTargetStackIfNeeded();
            return START_RETURN_INTENT_TO_CALLER;
        }
        if (reusedActivity != null) {
            //判断是直接复用栈以及其中的Activity 还是需要将Activity添加到复用栈中
            //后续会有对该方法的解析
            setTaskFromIntentActivity(reusedActivity);
            //如果不需要将新的ActivityRecord实例添加到任务栈中且没有清空可重用任务栈,则不需要做其他任何处理
            if (!mAddingToTask && mReuseTask == null) {
                //确保栈顶的元素处于resume状态
                resumeTargetStackIfNeeded();
                if (outActivity != null && outActivity.length > 0) {
                    outActivity[0] = reusedActivity;
                }
                return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
            }
        }
    }
    //Activity包名不存在说明不存在该Activity
    ................
    //判断是否可以直接复用栈顶Activity
    ................
    boolean newTask = false;
    //当前启动流程中该值为null
    final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
            ? mSourceRecord.getTask() : null;
    int result = START_SUCCESS;
    //判断是否需要新建TaskRecord来存储启动的Activity
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        newTask = true;
        //首先判断mReuseTask是否为null,如果为null则
        //新建任务栈,并将任务栈添加到ActivityStack栈顶,将ActivityRecord和新建的TaskRecord进行绑定并添加到任务栈顶
        result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
    //判断是否可以重用启动方任务栈中的Activity,如果可以重用则直接重用。否则将启动的Activity添加到启动方任务栈中
    } else if (mSourceRecord != null) {
        result = setTaskFromSourceRecord();
    //将Activity存放到指定任务栈中
    } else if (mInTask != null) {
        result = setTaskFromInTask();
    } else {
        //判断是否能够将当前Activity放入到当前已经获取焦点ActivityStack栈栈顶Activity的任务栈中,如果不能则新建任务栈存放Activity
        setTaskToCurrentTopOrCreateNewTask();
    }
    if (result != START_SUCCESS) {
        return result;
    }
  ................
    mTargetStack.mLastPausedActivity = null;
    mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
    //将任务栈设置为前台任务栈以及判断是否需要跳转Activity之间的过度动画
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
            mOptions);
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        //Activity没有获取都焦点,因此我们不能让该Activity处于resume状态,但是任然需要让它变得可见。
        //比如画中画模式下的Activity
        if (!mTargetStack.isFocusable()
                || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                && mStartActivity != topTaskActivity)) {
            mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            mService.mWindowManager.executeAppTransition();
        //一般都会进入到该条件中
        } else {
            if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
            }
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);
        }
    } else if (mStartActivity != null) {
        mSupervisor.mRecentTasks.add(mStartActivity.getTask());
    }
    mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
            preferredLaunchDisplayId, mTargetStack);

    return START_SUCCESS;
}

5.3 computeLaunchingTaskFlags

  在该方法中会根据启动方的Activity和当前要启动的Activity的LaunchMode判断是否新增FLAG_ACTIVITY_NEW_TASK,这里根据当前走的流程把无关的代码给省略掉了。

 private void computeLaunchingTaskFlags() {
    if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
    //因为第一个if语句这里不会走到所以省略
    ....................................
    } else {
        mInTask = null;
        //当前通过Intent要启动的界面有多个可以匹配,mStartActivity则是供用户选择的界面。或者Activity不显示
        //如果是这种情况则将该Activity添加到已经存在的任务栈中
        if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
                && mSourceRecord.inFreeformWindowingMode())  {
            mAddingToTask = true;
        }
    }
    //如果在启动Activity的时候没有指定进入到哪一个任务栈中并且:
    //(1)不是在Activity中启动当前Activity
    //(2)上一个界面的LaunchMode是singleInstance
    //(3)当前要启动Activity的LaunchMode是singleInstance或者singleTask
    // 如果是上面这三种情况则在LaunchFlags中添加FLAG_ACTIVITY_NEW_TASK标签
    if (mInTask == null) {
        if (mSourceRecord == null) {
            if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
            }
        } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        }
    }
}

5.4 getReusableIntentActivity

  该方法主要就是判断当前要启动的Activity是否需要添加到已经存在的栈中,如果需要则返回被重用栈的栈顶元素。

private ActivityRecord getReusableIntentActivity() {
    //如果FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_MULTIPLE_TASK一起出现,那么就会无条件的去新建一个任务栈存储Activity
    //否则就会先去查找是否存在能够复用的栈
    //如果要启动Activity的启动模式是singleInstance或者singleTask则也会去查找是否有可复用的栈
    boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
    //如果没有指定Task启动Activity并且要启动的Activity不会返回结果且上面计算结果为true则可以复用栈
    //如果设置了FLAG_ACTIVITY_NEW_TASK,那么在初始化的时候mStartActivity.resultTo就会被设为null,并且发送一个取消结果给上一个Activity
    putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
    ActivityRecord intentActivity = null;
    if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
       .........................
    } else if (putIntoExistingTask) {
        //如果要启动Activity的LaunchMode是singleInstance,则在回退栈中从栈顶向栈底依次遍历,查找到第一个满足条件的ActivityRecord并返回,满足如下条件:
        //(1)没有被finish;(2)能够在当前用户上显示;(3)userId和要启动Activity所在userId相同;(3)和要启动ActivityComponent相同;
        if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
           intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
                   mStartActivity.isActivityTypeHome());
        //分屏相关的flag
        } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
            intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
                    !(LAUNCH_SINGLE_TASK == mLaunchMode));
        } else {
            //查找亲和性和当前要启动Activity亲和性一致的任务栈,并返回顶部ActivityRecord
            intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId);
        }
    }
    return intentActivity;
}

5.5 setTargetStackAndMoveToFrontIfNeeded

  将可重用栈以及ActivityStack、ActivityRecord移到前台,也就是栈顶。

/**
*  intentActivity:可重用栈中栈顶的ActivityRecord
**/
private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
    //获取可复用栈所在ActivityStack
    mTargetStack = intentActivity.getStack();
    mTargetStack.mLastPausedActivity = null;
    //获取当前和用户交互的ActivityStack
    final ActivityStack focusStack = mSupervisor.getFocusedStack();
    //在FocusedStack的回退栈从栈顶向栈底查找第一个满足如下条件的Activity:
    //(1)没有finish;(2)没有被延迟resume;(3)不是要启动ActivityRecord实例对象;(4)能够在当前user下显示
    ActivityRecord curTop = (focusStack == null)
            ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
    final TaskRecord topTask = curTop != null ? curTop.getTask() : null;
    //如果能够重用的TaskRecord栈和处于ActivityStack栈顶的TaskRecord不相等
    //或者处于ActivityStack栈顶的TaskRecord是HomeStack等类型,则需要将复用的TaskRecord移到栈顶
    if (topTask != null
            && (topTask != intentActivity.getTask() || topTask != focusStack.topTask())
            && !mAvoidMoveToFront) {
        mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
        //如果不是在Activity中启动的页面或者启动方Activity所处任务栈位于栈顶
        if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
                mSourceStack.getTopActivity().getTask() == mSourceRecord.getTask())) {
            if (mLaunchTaskBehind && mSourceRecord != null) {
                intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
            }
            //判断是否会清除任务栈中所有的ActivityRecord,然后再将新建的ActivityRecord压入到栈中
            final boolean willClearTask =
                    (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
            if (!willClearTask) {
                //获取TaskRecord会被放入到哪一个ActivityStack中
                final ActivityStack launchStack = getLaunchStack(
                        mStartActivity, mLaunchFlags, mStartActivity.getTask(), mOptions);
                final TaskRecord intentTask = intentActivity.getTask();
                //如果可重用任务栈所在的ActivityStack和当前处于栈顶的ActivityStack相等
                //则将TaskRecord移动到ActivityStack栈顶,将ActivityRecord移动到TaskRecord栈顶
                if (launchStack == null || launchStack == mTargetStack) {
                    mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
                            mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
                    mMovedToFront = true;
                } 
                .......................
            }
        }
    }
    mTargetStack = intentActivity.getStack();
    //将ActivityStack移到栈顶
    if (!mMovedToFront && mDoResume) {
        mTargetStack.moveToFront("intentActivityFound");
    }
    ....................
    if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
        return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
    }
    return intentActivity;
}

5.6 setTaskFromIntentActivity

  在该方法中会对要启动Activity的LaunchMode以及Intent中的Flags判断是否需要将新的ActivityRecord添加到可重用的任务栈中,比如重用其中的ActivityRecord并清除其以上的所有ActivityRecord,或者是重用栈顶的ActivityRecord等。

/**
* mAddingToTask:用于标识是否需要将新的Activity实例添加到已存在的任务栈中
* mSourceRecord:标识是谁启动的Activity
* mReuseTask:可重用的TaskRecord
**/
private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
    //判断是否需要清除可重用的栈
    if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
        final TaskRecord task = intentActivity.getTask();
        //将栈中的所有ActivityRecord都移除
        task.performClearTaskLocked();
        mReuseTask = task;
        //设置栈根Activity信息为要启动Activity信息
        mReuseTask.setIntent(mStartActivity);
    //判断是否需要重用栈中的ActivityRecord,如果需要则将栈中该ActivityRecord以上的所有ActivityRecord都移除
    } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
            || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
        //如果是默认启动模式,则将存在的ActivityRecord实例以及其上的所有的ActivityRecord实例都移除
        ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
                mLaunchFlags);
        //如果top为null,说明在栈中没有找到对应的ActivityRecord实例或者因为默认启动模式将该ActivityRecord移除了
        if (top == null) {
            mAddingToTask = true;
            //将之前考虑的重用任务栈移除
            mStartActivity.setTask(null);
            //将启动ActivityRecord的源头更改为栈顶Activity
            mSourceRecord = intentActivity;
            final TaskRecord task = mSourceRecord.getTask();
            //获取存储当前Activity任务栈的ActivityStack栈
            if (task != null && task.getStack() == null) {
                mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
                        mLaunchFlags, mOptions);
                mTargetStack.addTask(task,
                        !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
            }
        }
    //如果要启动的Activity和可重用栈顶Activity是同一个实例对象,
    } else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
        //如果LaunchMode是singleTop则重用栈顶的Activity
        if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                    || LAUNCH_SINGLE_TOP == mLaunchMode)
                && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
            if (intentActivity.frontOfTask) {
                intentActivity.getTask().setIntent(mStartActivity);
            }
            deliverNewIntent(intentActivity);
        //如果当前启动Activity的IntentFilter和重用栈栈顶Activity的intentFilter不相同,则需要将ActivityRecord添加到任务栈中
        } else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
            mAddingToTask = true;
            mSourceRecord = intentActivity;
        }
    //需要建新的ActivityRecord添加到任务栈中
    } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
        mAddingToTask = true;
        mSourceRecord = intentActivity;
    //rootWasReset表示根Activity的Intent中带有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标签
    } else if (!intentActivity.getTask().rootWasReset) {
        intentActivity.getTask().setIntent(mStartActivity);
    }
}

5.7 setTaskFromReuseOrCreateNewTask

  该方法很简单,主要就是判断是否需要新建TaskRecord,并将ActivityRecord放入到TaskRecord栈顶,将TaskRecord放入到ActivityStack栈顶。

private int setTaskFromReuseOrCreateNewTask(
        TaskRecord taskToAffiliate, ActivityStack topStack) {
    //获取当前获取到焦点的ActivityStack
    mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
    //可重用TaskRecord为null,说明没有可重用栈可以存放要启动的ActivityRecord,则通过ActivityStack新建TaskRecord
    if (mReuseTask == null) {
        //在新建的过程中会将该task添加到ActivityStack栈顶
        final TaskRecord task = mTargetStack.createTaskRecord(
                mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
                mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
                mOptions);
        //将要启动的ActivityRecord实例对象添加到TaskRecord的栈顶
        addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
        updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);
    } else {
        addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
    }
    if (taskToAffiliate != null) {
        mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
    }
    //不能在固定任务栈中启动其他任务栈,否则会直接取消启动该Activity
    if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
        Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
        return START_RETURN_LOCK_TASK_MODE_VIOLATION;
    }
    //将ActivityStack移到前台
    if (mDoResume) {
        mTargetStack.moveToFront("reuseOrNewTask");
    }
    return START_SUCCESS;
}

5.7 setTaskFromSourceRecord

  判断是否可以重用任务栈中的Activity,如果可重用则直接重用。否则将该Activity添加到启动方的任务栈中。

private int setTaskFromSourceRecord() {
    //如果启动方的Activity所在TaskRecord处于栈顶并且已经被锁定则返回false
    if (mService.getLockTaskController().isLockTaskModeViolation(mSourceRecord.getTask())) {
        return START_RETURN_LOCK_TASK_MODE_VIOLATION;
    }
    //获取启动方Activity所在任务栈和ActivityStack
    final TaskRecord sourceTask = mSourceRecord.getTask();
    final ActivityStack sourceStack = mSourceRecord.getStack();
    //获取Activity会显示在哪个屏幕上
    final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
            : sourceStack.mDisplayId;
    //如下两种情况会改变ActivityStack:
    //(1)启动方Activity任务栈不是ActivityStack顶部任务栈
    //(2)Activity不允许显示在当前屏幕上
    final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
            || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
    if (moveStackAllowed) {
        mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.getTask(),
                mOptions);
        if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
            mTargetStack = mService.mStackSupervisor.getValidLaunchStackOnDisplay(
                    sourceStack.mDisplayId, mStartActivity);
        }
        if (mTargetStack == null) {
            mTargetStack = mService.mStackSupervisor.getNextValidLaunchStackLocked(
                    mStartActivity, -1 /* currentFocus */);
        }
    }
    //如果存储Activity的目标ActivityStack不存在,则设置为启动方ActivityStack
    if (mTargetStack == null) {
        mTargetStack = sourceStack;
    //如果目标ActivityStack和启动方ActivityStack不同则改变启动方ActivityStack
    } else if (mTargetStack != sourceStack) {
        sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
                DEFER_RESUME, "launchToSide");
    }
    final TaskRecord topTask = mTargetStack.topTask();
    //将目标ActivityStack和任务栈移到前台
    if (topTask != sourceTask && !mAvoidMoveToFront) {
        mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
                mStartActivity.appTimeTracker, "sourceTaskToFront");
    } else if (mDoResume) {
        mTargetStack.moveToFront("sourceStackToFront");
    }
    //判断是否可以重用任务栈中Activity
    if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
        ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
        mKeepCurTransition = true;
        if (top != null) {
            ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTask());
            deliverNewIntent(top);
            mTargetStack.mLastPausedActivity = null;
            if (mDoResume) {
                mSupervisor.resumeFocusedStackTopActivityLocked();
            }
            ActivityOptions.abort(mOptions);
            return START_DELIVERED_TO_TOP;
        }
    //在启动方的任务栈中查找是否存在要启动的Activity,如果存在则将该Activity移到任务栈前台并执行onNewIntent方法
    } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
        final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
        if (top != null) {
            final TaskRecord task = top.getTask();
            task.moveActivityToFrontLocked(top);
            top.updateOptionsLocked(mOptions);
            ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
            deliverNewIntent(top);
            mTargetStack.mLastPausedActivity = null;
            if (mDoResume) {
                mSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return START_DELIVERED_TO_TOP;
        }
    }
    //将启动的Activity添加到和启动方Activity所在任务栈相同的任务栈中
    addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
    return START_SUCCESS;
}

5.8 小结

  呼~,总算是把这个方法给理得差不多了,会发现启动一个新的Activity和它是否处于某一个应用并没有太大的联系,只是和要启动Activity的亲和性、LaunchMode以及Intent中的Flags相关,只是如果没有特别指定某一个应用中Activity的亲和性,那么该应用中的所有Activity亲和性都一样。大家可以通过如下的逻辑来确定一下Activity所处任务栈和具体的应用是否有关系:

  编写测试应用A和B,B中存在两个Activity分别是Activity1和Activity2,在应用A中启动应用B中的Activity2,不过得分为如下几种情况,Activity2是默认的启动模式,也就是standard:

(1)A应用启动B应用Activity2的时候在Intent中不添加任务Flag,并且不单独设置Activity2的亲和性,会发现启动的Activity2和A应用的Activity处于同一个任务栈中;

(2)A应用中启动B应用Activity2的时候添加FLAG_ACTIVITY_NEW_TASK标签,并且不单独设置Activity2的亲和性,会发现启动的Activity2会处于一个新的任务栈中;如果B应用已经启动了,并且其任务栈还存在,那么启动的Activity2会被添加到B应用所在任务栈;

(3)A应用中启动B应用Activity2的时候添加FLAG_ACTIVITY_NEW_TASK标签,并且单独设置Activity2的亲和性,会发现启动的Activity2会处于一个新的任务栈中;即使B应用的任务栈已经存在。

6、ActivityStack

6.1 resumeTopActivityInnerLocked

  在startActivityUnChecked方法中对任务栈等做了处理之后最终会调用到ActivityStackSuperVisor的resumeFocusedStackTopActivityLocked方法中,然后调用到ActivityStack的resumeTopActivityUncheckedLocked方法中通过调用resumeTopActivityInnerLocked方法来实现Activity的pause以及调用到ActivityThread中完成Activity的生命周期调用。大致分为了如下几个部分:

(1)判断是否需要暂停启动Activity,因为会出现如下情况:(1)当前存在Activity处于pausing状态;(2)需要被启动的栈顶Activity是否已经处于了resume状态等;具体可见代码;

(2)暂停上一个处于resume状态的Activity,如果在某一个Activity处于pausing状态的时候可以继续启动Activity,则停止启动当前Activity直到Activity暂停成功之后又回调到该函数中;

(3)判断要启动Activity应用进程是否存在,如果不存在则首先启动应用进程再回调到该函数启动栈顶的Activity;

(4)如果存在则通过Binder的方式调用到ActivityThread中执行Activity的生命周期方法。

/**
*   prev:不同调用场景表示不同的对象,一般来说是上一个处于resume状态的Activity,也有可能为null
*   options:启动Activity额外参数
*   return:true表示某一个Activity启动成功,false表示什么都没有发生
**/
 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (!mService.mBooting && !mService.mBooted) {
        return false;
    }
    //获取处于栈顶的元素,因为在startActivityUnChecked函数执行过程中我们已经将要启动Activity添加到了栈顶,所以这里一般获取的就是我们要启动的Activity
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    //判断是否存在需要被启动的Activity
    final boolean hasRunningActivity = next != null;
    //判断当前ActivityStack所在屏幕实例对象(ActivityDisplay)是否存在
    if (hasRunningActivity && !isAttached()) {
        return false;
    }
    //如果top Activity之前的Acitivty处于初始化状态,并且已经启动了一个窗口并显示了,则移除该窗口。比如在桌面启动一个应用,然后立马home键返回到桌面
    mStackSupervisor.cancelInitializingActivities();
    //为true表示当某一个Activity进入到后台的时候会调用onUserLeaveHint方法
    boolean userLeaving = mStackSupervisor.mUserLeaving;
    mStackSupervisor.mUserLeaving = false;
    //如果在当前ActivityStack中没有可以启动的Activity,那么就会去查找其他Focus类型的ActivityStack,并resume其中的顶部Activity
    //如果不存在Focus类型的ActivityStack,则resume桌面
    //因为在亮屏情况下总是要有Activity能够和用户交互
    if (!hasRunningActivity) {
        return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
    }
    next.delayedResume = false;
    //如果我们要启动的Activity已经启动了并且处于resume状态,则不需要再次重新启动
    if (mResumedActivity == next && next.isState(RESUMED)
            && mStackSupervisor.allResumedActivitiesComplete()) {
        executeAppTransition(options);
        return false;
    }
    //如果当前处于睡眠状态(灭屏),并且没有任何Activity处于resume状态,且顶部Activity处于pause状态,也不需要做其他任何事情,因为这就是我们想要的结果
    if (shouldSleepOrShutDownActivities()
            && mLastPausedActivity == next
            && mStackSupervisor.allPausedActivitiesComplete()) {
        executeAppTransition(options);
        return false;
    }
    //判断要启动Activity所在应用所在的user是否已经启动,如果没有启动则直接返回false
    if (!mService.mUserController.hasStartedUserState(next.userId)) {
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return false;
    }
    //从准备进入到stop状态的Activity列表中移除要启动的Activity实例
    mStackSupervisor.mStoppingActivities.remove(next);
    //从准备进入到睡眠状态的Activity列表中移除要启动的Activity实例对象
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    //从在完成任何操作之前等待一个新的Activity变为可见状态的Activity列表中移除要启动的Activity实例对象
    //比如在某一个Activity中打开另一个Activity,那么该Activity就会被添加到该列表中
    mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
    //判断当前是否存在Activity处于pausing状态,如果存在则不能做任何事情直到该Activity变化为paused、stopped或者stopping状态
    //因为当某一个Activity完成了pausing状态之后又会回调该方法来启动栈顶的Activity
    if (!mStackSupervisor.allPausedActivitiesComplete()) {
        return false;
    }
    //设置wakelock的workSource,workSource对象可用于判断两个wakelock是否相等
    mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
    boolean lastResumedCanPip = false;
    ActivityRecord lastResumed = null;
    final ActivityStack lastFocusedStack = mStackSupervisor.getLastStack();
    //判断上一个处于resume状态的Activity是否允许进入到画中画模式,关于画中画模式这里有介绍:
    //https://developer.android.com/guide/topics/ui/picture-in-picture?hl=zh-cn
    if (lastFocusedStack != null && lastFocusedStack != this) {
        lastResumed = lastFocusedStack.mResumedActivity;
        if (userLeaving && inMultiWindowMode() && lastFocusedStack.shouldBeVisible(next)) {
            userLeaving = false;
        }
        lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState(
                "resumeTopActivity", userLeaving /* beforeStopping */);
    }
    //当上一个应用处于pausing状态的同时也可以启动另一个应用
    final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
            && !lastResumedCanPip;
    //停止非focus类型stack中处于resume状态的Activity
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
    //停止当前处于resume状态的Activity
    if (mResumedActivity != null) {
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    //如果当前存在Activity处于pausing状态,并且要启动的Activity不能在另一个应用处于pausing状态的时候启动
    //也就是暂停Activity和启动Activity同时存在,则会先执行暂停Activity流程
    //如果要启动Activity所在应用进程存在,则将该进程添加到最近最少使用队列的头部
    if (pausing && !resumeWhilePausing) {
        if (next.app != null && next.app.thread != null) {
            mService.updateLruProcessLocked(next.app, true, null);
        }
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        if (lastResumed != null) {
            lastResumed.setWillCloseOrEnterPip(true);
        }
        return true;
    //如果当前Activity启动不会等待另一个Activity进入到pause状态,那么当另一个Activity进入到pause状态之后回调该方法当前Activity可能已经启动成功了
    //这种情况就不需要做其他操作了,直接返回true
    } else if (mResumedActivity == next && next.isState(RESUMED)
            && mStackSupervisor.allResumedActivitiesComplete()) {
        executeAppTransition(options);
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }
    //如果当前Activity是mLastNoHistoryActivity,也就是离开这个Activity,该Activity就会从任务栈中移除
    //并且当前设备处于睡眠状态,那么在系统被唤醒之后如果新启动了一个Activity,那么mLastNoHistoryActivity会被结束
    if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
            !mLastNoHistoryActivity.finishing) {
        requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
                null, "resume-no-history", false);
        mLastNoHistoryActivity = null;
    }
    //如果当前要启动的Activity和上一个处于resume状态的Activity不是同一个实例
    //并且pre没有被添加到mActivitiesWaitingForVisibleActivity列表中,则将其添加到该列表中
    if (prev != null && prev != next) {
        if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
                && next != null && !next.nowVisible) {
            mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev);
        } else {
            if (prev.finishing) {
                prev.setVisibility(false);
            } else {
            }
        }
    }
    //确保启动的Activity所在应用处于运行状态
    try {
        AppGlobals.getPackageManager().setPackageStoppedState(
                next.packageName, false, next.userId);
    } catch (RemoteException e1) {
    } catch (IllegalArgumentException e) {
    }
    //通知windowManager上一个处于resume的Activity会很快被隐藏,并设置是否有过渡动画
    .......................
    ActivityStack lastStack = mStackSupervisor.getLastStack();
    //如果要启动Activity所在进程存在则通过Binder的方式调用到ActivityThread中开始执行生命周期方法
    //否则通过Process启动对应进程之后再启动Activity
    if (next.app != null && next.app.thread != null) {
        //上一个处于resume状态的Activity是否是分屏或者不是全屏
        final boolean lastActivityTranslucent = lastStack != null
                && (lastStack.inMultiWindowMode()
                || (lastStack.mLastPausedActivity != null
                && !lastStack.mLastPausedActivity.fullscreen));
        synchronized(mWindowManager.getWindowManagerLock()) {
            //如果要启动Activity不可见、处于stop状态或者上一个Activity处于分屏状态则设置要启动Activity可见
            //以便能够在WindowManager中正确设置过渡动画
            if (!next.visible || next.stopped || lastActivityTranslucent) {
                next.setVisibility(true);
            }
            //记录Activity启动时间
            next.startLaunchTickingLocked();
            //获取上一个处于resume状态的Activity
            ActivityRecord lastResumedActivity =
                    lastStack == null ? null :lastStack.mResumedActivity;
            //获取要启动Activity当前状态
            final ActivityState lastState = next.getState();
            mService.updateCpuStats();
            //设置要启动Activity要进入的状态为resume
            next.setState(RESUMED, "resumeTopActivityInnerLocked");
            //将要启动Activity所在进程添加到最近最少使用列表中
            mService.updateLruProcessLocked(next.app, true, null);
            updateLRUListLocked(next);
            //更新进程优先级
            mService.updateOomAdjLocked();
            boolean notUpdated = true;
            //如果屏幕配置项发生了变化,比如发生了横竖屏切换,判断新启动的Activity是否能够适配新的配置,如果不能则会被relaunch
            if (mStackSupervisor.isFocusedStack(this)) {
                notUpdated = !mStackSupervisor.ensureVisibilityAndConfig(next, mDisplayId,
                        true /* markFrozenIfConfigChanged */, false /* deferResume */);
            }
            //如果屏幕配置发生变化之后重新启动了一个新的Activity实例,那么我们要确保该Activity仍然处于栈顶
            if (notUpdated) {
                ActivityRecord nextNext = topRunningActivityLocked();
                //如果当前处于栈顶的Activity和需要被启动的Activity不属于同一个Activity实例对象,则启动栈顶的Activity
                if (nextNext != next) {
                    mStackSupervisor.scheduleResumeTopActivities();
                }
                //设置要启动的Activity为可见
                if (!next.visible || next.stopped) {
                    next.setVisibility(true);
                }
                //Activity启动成功并设置要启动Activity状态为resume状态
                next.completeResumeLocked();
                return true;
            }
            try {
                //获取能够发送给客户端的实体类对象,其中包含了函数回调和生命周期状态
                final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
                        next.appToken);
                ArrayList<ResultInfo> a = next.results;
                //回调到Activity的onActivityResult方法中
                if (a != null) {
                    final int N = a.size();
                    if (!next.finishing && N > 0) {
                        transaction.addCallback(ActivityResultItem.obtain(a));
                    }
                }
                //回调到Activity的onNewIntent方法中
                if (next.newIntents != null) {
                    transaction.addCallback(NewIntentItem.obtain(next.newIntents,
                            false /* andPause */));
                }
                next.notifyAppResumed(next.stopped);
                next.sleeping = false;
                mService.getAppWarningsLocked().onResumeActivity(next);
                mService.showAskCompatModeDialogLocked(next);
                next.app.pendingUiClean = true;
                next.app.forceProcessStateUpTo(mService.mTopProcessState);
                next.clearOptionsLocked();
                //设置该Activity要执行的生命周期回调
                transaction.setLifecycleStateRequest(
                        ResumeActivityItem.obtain(next.app.repProcState,
                                mService.isNextTransitionForward()));
                //最后通过调用到ClientLifecycleManager对象中,通过要启动Activity的binder对象调用到ApplicationThread对象的scheduleTransaction方法中
                //也就是我们启动一个Activity之前首先需要构建一个ClientTransaction对象,然后通过Binder的方式调用到ActivityThread中
                //并将ClientTransaction对象传递到ActivityThread中完成要启动Activity的生命周期调用
                mService.getLifecycleManager().scheduleTransaction(transaction);
            } catch (Exception e) {
                next.setState(lastState, "resumeTopActivityInnerLocked");
                if (lastResumedActivity != null) {
                    lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
                }
                if (!next.hasBeenLaunched) {
                    next.hasBeenLaunched = true;
                } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null
                        && lastStack.isTopStackOnDisplay()) {
                    next.showStartingWindow(null /* prev */, false /* newTask */,
                            false /* taskSwitch */);
                }
                mStackSupervisor.startSpecificActivityLocked(next, true, false);
                return true;
            }
        }
        try {
            //Activity完成了启动,设置其状态为resume状态
            next.completeResumeLocked();
        } catch (Exception e) {
            requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
                    "resume-exception", true);
            return true;
        }
    //如果要启动Activity的应用进程不存在则先新建应用进程再启动Activity
    } else {
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
        }
        //最终调用到Process中通过socket的方式启动Activity所在进程
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    return true;
}

  其实整个过程我们可以大致分为三个部分去看:

(1)判断是否能够继续启动Activity;

(2)停止上一个处于resume状态的Activity;

(3)判断是否需要启动应用进程,如果不需要则通过Binder的方式调用到ActivityThread中执行启动Activity生命周期函数;如果不存在进程,则首先创建进程再回调到该方法中启动栈顶的Activity。

7、框架中如何通过Binder的方式调用到应用层

  在框架层需要调用到Activity的生命周期函数的时候,会将Activity要进入到的最终状态、函数回调等信息封装在可序列化对象ClientTransaction中,然后通过该对象中存储的应用进程Binder对象通过Binder的方式调用到应用层执行生命周期方法。这里来看一下这个过程在框架层所涉及到的源码部分。

7.1 scheduleTransaction

  首先从AMS获取到ClientLifecycleManager相关实例对象,然后调用该实例对象的scheduleTransaction方法,打开该类发现有很多重载的scheduleTransaction方法,但是最后都会调用到如下函数中:

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    //获取可以和上层应用通信的Binder对象
    final IApplicationThread client = transaction.getClient();
    //调用到ClientTransaction对象中通过Binder的方式调用到应用层
    transaction.schedule();
    //如果通信方不是Binder对象,那说明是在同一个进程中通信,那么在执行完上面的方法之后,则可以将所有对象都回收
    if (!(client instanceof Binder)) {
        transaction.recycle();
    }
}

  接着继续看一下ClientTransaction对象实例中的schedule方法,会发现就一行代码。直接通过Binder的方式调用到客户端,并将当前实例对象传递给应用层;后续就是Activity生命周期了,这个下一篇文章再进行讲解。

public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}

三、总结

  呼~,花了一两周的时间写了一万多字,总算是把AMS启动Activity的源码部分解析得差不多了,当然里面还有很多细节部分非常值得去深度挖掘。这里因为篇幅和时间原因对很多地方都一笔略过了,没有深入的去解析,不过这并不代表它不重要,只是可能在当前分析的流程中没有涉及到而已。通过对源码的解析其实AMS启动Activity的逻辑大致可以分为如下几个部分:

(1)到PackageManagerService中查看是否存在该Activity所对应的应用信息等;

(2)判断是否能够正常启动Activity;

(3)判断是否可以复用已经存在的栈以及栈中的Activity实例对象;

(4)如果不能复用则新建任务栈来存在对应的Activity实例对象,并将Activity实例对象放置到栈顶供后续启动;

(5)通过Binder的方式暂停当前处于resume状态的Activity;

(6)判断要启动的Activity所在应用进程是否存在,如果不存在则首先创建进程再启动Activity;

(7)如果存在则通过Binder的方式调用到对应应用进程中执行生命周期方法;

(8)通过Binder的方式通知上一个处于resume状态的Activity进入到stop状态;