查看原文
其他

Activity系列--Activity启动-源码分析

牛晓伟 牛晓伟
2024-08-24

Activity跳转那一节介绍了Activity跳转相关的使用和基础知识,那这节就来升华一下:分析下Activity的启动流程,看它到底是怎么启动的.(下面的分析都是基于app进程已经存在,并且要启动的Activity没有启动过)

Activity启动原理

start-activity
start-activity

上面两张图分别展示了:app启动app内某个Activity的过程和app启动其他app某个Activity的过程,当然上面的图中都是以app/app1进程本身已经存在为前提,app进程不存在的话还需要涉及到进程创建的过程(进程创建属于这节的讨论范畴)

先来介绍几个知识点:

  • ActivityManagerService(为了方便简称为AMS)它位于系统进程,系统进程里面有很多的服务(比如WindowMnagerService),AMS只是其中的一个,它管理android中的四大组件.
  • app是位于它自己进程的,与系统进程完全不同.

不管是启动app内还是app外的Activity,都会经历三个过程:

  1. app请求AMS启动Activity(在app进程)
  2. AMS处理请求(在系统进程)
  3. app接收并处理AMS发出的信息(在app进程)

那就从这三个过程来进行分析

1.app请求AMS启动Activity

在前面章节中介绍过,启动(或跳转)Activity会先配置一个Intent,这个Intent存放的数据可是很丰富了:包含了启动Activity的信息,传递给Activity的数据,甚至还有启动Activity的方式等等.app进程与AMS不处于同一进程,它们之间的通信使用的是binder,Intent会在"binder这条搭建好的公路"上传递到AMS.

2.AMS处理请求

AMS拿到Intent后会做以下处理:

2.1.根据Intent去查询Activity的信息,那去哪查呢?答案是PMS服务

既然涉及到了PMS那就先来了解下它,PMS是PackageManagerService的简称,它也是一个运行在系统进程内的服务。它主要做的事情就是把手机上安装的所有apk里面的AndroidManifest(清单)文件里面的信息解析出来并且存储在内存。还记得在编写一个Activity的时候,需要在AndroidManifest文件中配置该Activity,最终清单文件及Activity等信息全部会打包到apk的文件中。AndroidManifest文件主要就是给PMS来用的,还记得在清单文件中配置Activity的时候,会为Activity配置intent-filter吗?intent-filter里面会包含action,category,data这些配置项目,这些信息也会被PMS解析出来。

为啥要去查询Activity的信息呢,原因是这样的:Intent分为显示和隐示。对于显示Intent,虽然Intent中指明了目标Activity的class信息,但是这个信息太少了,Activity的启动模式,权限等等其他信息完全不知道. 对于隐示Intent,那更需要去查了,隐示的根本就不知道目标Activity是谁.

查到来的Activity信息大体有:目标Activity的class信息,包名,权限,启动模式,action,data等等.

若PMS根据Intent没有查找到Activity,则停止后面的流程,把错误信息返回给app;否则继续后面的流程

2.2.各种检查,校验

需要对启动的参数,启动的进程等等并且结合查询到的Activity信息进行检查,校验.比如权限校验了(有些Activity不是谁都能启动的),是否对外可以启动等校验流程,如果一系列的校验都通过了,继续后面的流程.

2.3.保存启动的Activity,并且放入task

把要启动的Activity信息记录下来(记录的类叫ActivityRecord),依据app传递过来的Intent设置的flag信息及启动Activity的launchmode等信息来决定是否要创建task(对应的类Task)。若新创建了task,则把ActivityRecord放入task中,否则在原先的task放入ActivityRecord。

2.4.把数据返回给app

若启动的Activity对应的进程没有启动,需要等待进程启动完成. AMS会把很多重要的数据(如Activity信息,Intent,token等)数据(数据会被放入ClientTransaction这个类)中返回给app.

到此AMS的流程就结束了。

3.app接收并处理AMS发出的信息

app的AtivityThread的ApplicationThread类的scheduleTransaction方法会收到AMS发过来的ClientTransaction数据, 从中拿到目标Activity信息,通过反射初始化目标Activity实例,实例初始化完成后会接着调用它的onAttach,onCreate回调方法.

同时AtivityThread类也会把启动的Activity记录下来(记录的类是ActivityClientRecord),最终会把AMS传递过来的token作为key,ActivityClientRecord作为value存放在ArrayMap中。

小结

Activity的启动的流程如下:

  1. app把包含启动Activity等其他数据的Intent通过binder调用发送给AMS
  2. AMS通知PMS依据Intent解析出对应的Activity的信息.若解析成功,则对各种参数,进程信息结合解析到的Activity信息进行检查,校验.若成功则记录下启动Activity并把记录放入创建或已有的task中. 把Activity信息,Intent等数据通过binder调用发送给app
  3. app那到Activity信息,通过反射实例化Activity,并且调用它的onAttach,onCreate方法.

Activity启动源码分析

在进行源码分析之前先介绍下用到的前置知识

前置知识

进程之间通信:android app进程之间使用binder进行通信,下面的内容会涉及到binder(关于binder通信后面的章节会介绍) 线程之间通信:线程之间通信方式很多,android中线程之间通信一般都使用handler,下面介绍的内容就会涉及到handler。

相关的类app相关:

frameworks/base/core/java/android/app/Activity.java frameworks/base/core/java/android/app/Instrumentation.java frameworks/base/core/java/android/app/ActivityThread.java

ams相关:

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java

pms相关:

frameworks/base/core/java/android/content/pm/ResolveInfo.java frameworks/base/core/java/android/content/pm/ActivityInfo.java

(以上源码版本是android 12)

关键类的介绍ActivityThread:这个类的名字看上去容易造成误导,总以为是与Activity相关的Thread。其实它处理的事情可多了,在app进程创建成功后,ActivityThread中会启动一个主线程,这个主线程不断的在循环中取消息和执行消息,这样就能保证app一直能保持”活着“的状态。这个类还执行四大组件的初始化,并根据AMS发的指令调用四大组件的相应回调方法,并且还执行Application的相关初始化等工作。一个app进程中只有一个ActivityThread实例。ApplicationThread:这个类继承了IApplicationThread.Stub,它也是Binder类型。它的主要作用就是接收来自AMS发送过来的消息。 Instrumentation:这个类的主要作用是对AMS传递过来四大组件及Application对应的字符串类型的Class,通过发射进行初始化;这个类还负责调用四大组件和Application的回调方法(比如Activity的onCreate方法,Application的onCreate方法)ActivityClientRecord:这个类的主要作用就是在app进程保存启动的Activity等信息与AMS的ActivityRecord是一一对应关系。

ActivityTaskManagerService:简称ATMS,原先老版本的android代码里面是没有ATMS这个类的的。因为原先的AMS代码越来越臃肿,功能也很复杂(Service,Activity,Broadcast,ContentProvider相关的接口都在AMS中)。因此到了后面的android版本就AMS的代码进行了重构,把Activity相关的工作都放在了ATMS类中。ActivityStarter:这个类的主要职责就是根据各种信息来决定如何启动Activity,并且根据各种信息来决定是把Activity放在一个新task中还是放在roottask中,为了节约宝贵的内存,该类的实例会被缓存在ActivityStartController类中。ActivityRecord:这个类的主要作用是在系统进程中保存启动的Activity等信息。ActivityRecord$Token:Token这个类,在原理篇提过,它是ActivityRecord与ActivityClientRecord的桥梁。

开始分析

如原理篇介绍,启动Activity有如下三个过程:

  1. app请求AMS启动Activity(在app进程)
  2. AMS处理请求(在系统进程)
  3. app接收并处理AMS发出的信息(在app进程) 因此整个源码分析也以这三个过程来进行分析。

1.app请求AMS启动Activity

从Activity的startActivity方法开始吧,下面方法的执行都在app进程。

1.1 Activity#startActivity

    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        ......省略代码
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            //因为options为null,因此进入这个环节
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            //增加了requestCode为-1的参数,代表不需要关注这个Activity的返回数据
            startActivityForResult(intent, -1);
        }
    }

1.2 Activity#startActivityForResult

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
        //调用同名方法,增加了一个Bundle为null的参数
        startActivityForResult(intent, requestCode, null);
    }

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        //主要分析mParent== null的情况
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            //调用mInstrumentation.execStartActivity方法,
            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());
            }
            //对于requestCode大于0的情况,则把mStartedActivity置为true
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            ......省略代码
        }
    }

上面的方法主要做的事情:会根据mParent是否存在执行不同的逻辑,但是最终都会调用到同一方法。咱们主要分析mParent== null的情况。

介绍下mInstrumentation.execStartActivity方法的几个关键参数:

  • who:类型为Activity
  • contextThread:类型为IBinder,mMainThread.getApplicationThread()获取的是一个类型为IApplicationThread的对象,这个对象同时也是一个Binder对象,它会被传递给AMS,AMS拿到它可以与app进程进行通信。 mMainThread是ActivityThread的实例,一个进程内就进存在一个
  • token:类型IBinder,mToken是它的值,在上面原理篇介绍过。
  • intent:启动信息,参数等都在Intent内
  • requestCode:若是调用startActivityForResult方法,这个参数有用,否则没用。它若存在会传递给启动的Activity,Activity finish后并且调用了setResult方法,这个参数会被返回。当前值为-1

1.3 Instrumentation#execStartActivity

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        //把contextThread转换为IApplicationThread
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        ......省略代码
        try {
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            //binder调用到ActivityTaskManagerService
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getOpPackageName(), who.getAttributionTag(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                    target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
            notifyStartActivityResult(result, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

该方法做的事情主要是为intent添加一些额外的信息外,最终通过binder调用把参数发送到系统进程。

**ActivityTaskManager.getService()**:获取的是ActivityTaskManagerService在app进程内的代理类的实例,这个代理类实现了IActivityTaskManager,同时它也是BinderProxy类型。

介绍下ActivityTaskManager.getService().startActivity方法的几个关键的参数:

  • caller:它的类型是IApplicationThread,whoThread是它的值
  • callingPackage:String类型,代表启动者的包名。who.getOpPackageName()是它的值
  • intent:自不必多说,包含启动的各项数据
  • token:代表发起启动的Activity(称它为启动者),在app进程它的类型是BinderProxy
  • requestCode:若使用的是startActivity这方法,这值是-1;否则是上层传递的值

小结

用一张时序图进行小结

2. AMS处理请求

下面方法的执行都在系统进程中

2.1 ActivityTaskManagerService#startActivity

    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions) {
        //增加一个userId信息它的值是UserHandle.getCallingUserId()
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

    @Override
    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions, int userId) {
        //增加一个validateIncomingUser参数,它的值为true
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

     private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        assertPackageMatchesCallingUid(callingPackage);
        enforceNotIsolatedCaller("startActivityAsUser");

        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        [2.1 obtainStarter]
        int res = getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
                .execute();
        return res;
    }

[2.1 obtainStarter]getActivityStartController().obtainStarter方法的介绍。

getActivityStartController()会获取一个ActivityStartController类的实例,ActivityStartController中缓存了ActivityStarter,这样就不需要每次都new一个ActivityStarter出来,浪费宝贵的内存了。

obtainStarter方法会获取一个已有或创建一个新的ActivityStarter类实例,这个类的主要职责就是根据各种信息来决定如何启动Activity,并且根据各种信息来决定是把Activity放在一个新task中还是放在roottask中。

初始化ActivityStarter的几个关键参数介绍:

  • caller:IApplicationThread类型,app进程中传递过来的IApplicationThread,它现在的类型是BinderProxy
  • callingPackage:String类型,启动者包名,有了这个信息对于分析问题是非常重要的,比如:有时候Activity莫名其妙的就启动了,这时候去看callingPackage就可以知道是谁启动的。
  • resultTo:IBinder类型,代表发起启动的Activity(启动者),在app进程中它的类型是BinderProxy。进入系统进程后它的类型会被转换为Binder。(这是binder机制,后面介绍binder机制的时候会介绍)

ActivityStarter定义了一套可以链式调用的方法,简单看下几个方法:

    ActivityStarter setProfilerInfo(ProfilerInfo info) {
        mRequest.profilerInfo = info;
        return this;
    }

    ActivityStarter setGlobalConfiguration(Configuration config) {
        mRequest.globalConfig = config;
        return this;
    }

    ActivityStarter setUserId(int userId) {
        mRequest.userId = userId;
        return this;
    }

在设置完属性后,返回this,这样就可以接着在调用另外的设置方法了。ActivityStarter设置的属性都存放在了mRequest这个实例中。

初始化完毕ActivityStarter,会调用它的execute方法。

2.2 ActivityStarter#execute

    int execute() {
        try {
            省略代码......

            final LaunchingState launchingState;
            synchronized (mService.mGlobalLock) {
                //获取启动者
                final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
                //获取callingUid
                final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
                        ?  Binder.getCallingUid() : mRequest.realCallingUid;
                launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
                        mRequest.intent, caller, callingUid);
            }

            // If the caller hasn't already resolved the activity, we're willing
            // to do so here. If the caller is already holding the WM lock here,
            // and we need to check dynamic Uri permissions, then we're forced
            // to assume those permissions are denied to avoid deadlocking.
            //activityInfo为null 则需要去解析
            if (mRequest.activityInfo == null) {
                mRequest.resolveActivity(mSupervisor);
            }

            int res;
            //启动的时候使用mService.mGlobalLock锁保持同步
            synchronized (mService.mGlobalLock) {
                final boolean globalConfigWillChange = mRequest.globalConfig != null
                        && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
                final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
                
                省略代码......

                res = executeRequest(mRequest);

                省略代码......

                if (mRequest.waitResult != null) {
                    mRequest.waitResult.result = res;
                    res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
                            launchingState);
                }
                return getExternalResult(res);
            }
        } finally {
            onExecutionComplete();
        }
    }

该方法主要做了以下事情:

  1. 若mRequest.activityInfo为null,回调用mRequest.resolveActivity(mSupervisor)方法开始解析过程,最终会进入PMS(PackageManagerService)中根据intent解析出ResolveInfo和ActivityInfo
  2. 调用executeRequest方法开始进入下个流程

PMS根据intent解析ResolveInfo和ActivityInfo的流程在这就不赘述了,不过有必要介绍下ResolveInfo和ActivityInfo这两个类。

ResolveInfo

看下它的几个关键属性:

public class ResolveInfo implements Parcelable {
    private static final String TAG = "ResolveInfo";
    private static final String INTENT_FORWARDER_ACTIVITY =
            "com.android.internal.app.IntentForwarderActivity";

    /**
     * The activity or broadcast receiver that corresponds to this resolution
     * match, if this resolution is for an activity or broadcast receiver.
     * Exactly one of {@link #activityInfo}, {@link #serviceInfo}, or
     * {@link #providerInfo} will be non-null.
     */
    public ActivityInfo activityInfo;

    /**
     * The service that corresponds to this resolution match, if this resolution
     * is for a service. Exactly one of {@link #activityInfo},
     * {@link #serviceInfo}, or {@link #providerInfo} will be non-null.
     */
    public ServiceInfo serviceInfo;

    /**
     * The provider that corresponds to this resolution match, if this
     * resolution is for a provider. Exactly one of {@link #activityInfo},
     * {@link #serviceInfo}, or {@link #providerInfo} will be non-null.
     */
    public ProviderInfo providerInfo;

    /**
     * An auxiliary response that may modify the resolved information. This is
     * only set under certain circumstances; such as when resolving instant apps
     * or components defined in un-installed splits.
     * @hide
     */
    public AuxiliaryResolveInfo auxiliaryInfo;

    /**
     * Whether or not an instant app is available for the resolved intent.
     */
    public boolean isInstantAppAvailable;

    /**
     * The IntentFilter that was matched for this ResolveInfo.
     */
    public IntentFilter filter;

    省略代码......
}

ResolveInfo实现了Parcelable,代表它可以通过binder在进程之间进行传递。在AndroidManifest配置的四大组件解析完后的数据会放入ResolveInfo类中。

如上,它里面的几个关键属性:

  • activityInfo,serviceInfo,providerInfo:分别代表Activity,Broadcast,Service,ContentProvider
  • filter:在AndroidManifest里面配置的Intent-filter这一项

用一个AndroidManifest.xml例子来说下ResolveInfo, AndroidManifest.xml有如下信息:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.lifecycledemo">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.LifecycleDemo">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SecondActivity"/>
    </application>

</manifest>

上面的清单文件信息会被解析成两个ResolveInfo: 其中一个它的activityInfo包含的信息是MainActivity,它的filter包含的信息是action为android.intent.action.MAIN,category为android.intent.category.LAUNCHER。 另一个它的activityInfo包含的信息是SecondActivity,它的filter为null

介绍完ResolveInfo,介绍下ActivityInfo这个类。

ActivityInfo主要显示它的几个关键属性:

public class ActivityInfo extends ComponentInfo implements Parcelable {
    public int theme;
    public int launchMode;
    public String taskAffinity;
    public String name;
    public String packageName;

    省略代码......
}

ActivityInfo包含了在AndroidManifest里面配置的Activity的信息,它上面的几个属性:

  • theme:Activity的主题
  • launchMode:配置的Activity的启动模式
  • taskAffinity:指定Activity放在哪个名字下面的task
  • name:Activity的完整的classname
  • packageName:包名

2.3 ActivityStarter#executeRequest

    private int executeRequest(Request request) {
        if (TextUtils.isEmpty(request.reason)) {
            throw new IllegalArgumentException("Need to specify a reason.");
        }
        mLastStartReason = request.reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();
        mLastStartActivityRecord = null;

        final IApplicationThread caller = request.caller;
        Intent intent = request.intent;
        NeededUriGrants intentGrants = request.intentGrants;
        String resolvedType = request.resolvedType;
        ActivityInfo aInfo = request.activityInfo;
        ResolveInfo rInfo = request.resolveInfo;
        final IVoiceInteractionSession voiceSession = request.voiceSession;
        final IBinder resultTo = request.resultTo;
        String resultWho = request.resultWho;
        int requestCode = request.requestCode;
        int callingPid = request.callingPid;
        int callingUid = request.callingUid;
        String callingPackage = request.callingPackage;
        String callingFeatureId = request.callingFeatureId;
        final int realCallingPid = request.realCallingPid;
        final int realCallingUid = request.realCallingUid;
        final int startFlags = request.startFlags;
        final SafeActivityOptions options = request.activityOptions;
        Task inTask = request.inTask;

        int err = ActivityManager.START_SUCCESS;
        
        省略代码......

        WindowProcessController callerApp = null;
        //根据caller获取callerApp
        if (caller != null) {
            callerApp = mService.getProcessController(caller);
            if (callerApp != null) {
                callingPid = callerApp.getPid();
                callingUid = callerApp.mInfo.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
                        + ") when starting: " + intent.toString());
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }

        //获取userId
        final int userId = aInfo != null && aInfo.applicationInfo != null
                ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
        if (err == ActivityManager.START_SUCCESS) {
            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(truetruetruefalse)
                    + "} from uid " + callingUid);
        }

        ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        if (resultTo != null) {
            //根据resultTo找到sourceRecord,resultTo是一个Token,sourceRecord启动者
            sourceRecord = mRootWindowContainer.isInAnyTask(resultTo);
            if (DEBUG_RESULTS) {
                Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
            }
            if (sourceRecord != null) {
                //如果是startActivityForResult启动的,则对resultRecord赋值
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }

        final int launchFlags = intent.getFlags();
        
        省略各种出错信息的判断代码......

        //根据resultRecord找到resultRootTask
        final Task resultRootTask = resultRecord == null
                ? null : resultRecord.getRootTask();

        if (err != START_SUCCESS) {
            if (resultRecord != null) {
                resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
                        null /* data */, null /* dataGrants */);
            }
            SafeActivityOptions.abort(options);
            return err;
        }

        省略权限判断等各种其他代码......

        //构造ActivityRecord
        final ActivityRecord r = new ActivityRecord.Builder(mService)
                .setCaller(callerApp)
                .setLaunchedFromPid(callingPid)
                .setLaunchedFromUid(callingUid)
                .setLaunchedFromPackage(callingPackage)
                .setLaunchedFromFeature(callingFeatureId)
                .setIntent(intent)
                .setResolvedType(resolvedType)
                .setActivityInfo(aInfo)
                .setConfiguration(mService.getGlobalConfiguration())
                .setResultTo(resultRecord)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setComponentSpecified(request.componentSpecified)
                .setRootVoiceInteraction(voiceSession != null)
                .setActivityOptions(checkedOptions)
                .setSourceRecord(sourceRecord)
                .build();

        mLastStartActivityRecord = r;

        //调用startActivityUnchecked方法开始进入下个启动
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);

        if (request.outActivity != null) {
            request.outActivity[0] = mLastStartActivityRecord;
        }

        return mLastStartActivityResult;
    }

该方法主要做了以下工作:

  1. 在启动之前,对各种基础的异常进行检测,发现有异常则退出启动Activity流程
  2. 检测通过后构造了一个ActivityRecord实例
  3. 开始进入启动Activity的流程

构造了一个ActivityRecord实例,对这个实例初始化主要用到了以下参数:

  • callerApp:WindowProcessController类型,主要是启动者相关的信息
  • callingPid:启动者的进程id
  • callingUid:启动者的id,每个安装的app都会分配一个唯一的id,这个id在当前的用户空间内是不会变化的
  • intent:把intent存起来
  • aInfo:从AndroidManifest中解析出来的Activity信息
  • resultRecord:对于startActivityForResult启动activity时候的启动这信息,用于把返回结果返回给resultRecord
  • requestCode:对于startActivityForResult启动activity时候传递的值
  • sourceRecord:启动者,代表谁启动了Activity

ActivityRecord就把app进程要启动的Activity及相关的其他信息保存下来了,要注意这里提到的Activity和app进程中要启动的Activity是两码事。

该方法调用startActivityUnchecked方法进入启动的下个流程,调用的时候关键参数有:

  • r: ActivityRecord类型
  • sourceRecord:启动者,是一个ActivityRecord
  • doResume:它的值为true
  • options:它的值为checkedOptions,checkedOptions的值现在是为null
  • inTask:代表启动的Activity存放的task,当前它的值为null(因为在初始化ActivityRecord的时候就没有设置它)

2.4 ActivityStarter#startActivityUnchecked

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, Task inTask,
                boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        int result = START_CANCELED;
        final Task startedActivityRootTask;

        省略代码......

        try {
            mService.deferWindowLayout();
            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
            [2.5]
            //doResume:true,options值为null,inTask:null
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
        } finally {
            省略代码......
        }

        postStartActivityProcessing(r, result, startedActivityRootTask);

        return result;
    }

2.5 ActivityStarter#startActivityInner

    int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
            
        //调用这个方法重置activityStarter的各种数据
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor, restrictedBgActivity);

        //设置launchmode
        computeLaunchingTaskFlags();
        //查找mSourceRootTask
        computeSourceRootTask();

        mIntent.setFlags(mLaunchFlags);
        
        //获取reusabletask
        final Task reusedTask = getReusableTask();

        省略冻结task代码......

        // Compute if there is an existing task that should be used for.
        //如果reusedTask为null,则调用computeTargetTask()方法获取
        final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
        //newTask是否是新task
        final boolean newTask = targetTask == null;
        mTargetTask = targetTask;

        
        computeLaunchParams(r, sourceRecord, targetTask);

        省略代码......

        //如果mTargetRootTask为null,则调用getLaunchRootTask方法会获取或者创建一个task
        if (mTargetRootTask == null) {
            mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
        }
        //如果是新的task,则进行创建task流程,并且把ActivityRecord放置在task中
        if (newTask) {
            final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
            setNewTask(taskToAffiliate);
        } else if (mAddingToTask) {
            //把ActivityRecord放置在找到的task中
            addOrReparentStartingActivity(targetTask, "adding to task");
        }

        省略代码......
        
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            //不关注这块逻辑,直接看下面的else
            if (!mTargetRootTask.isTopActivityFocusable()
                    || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                    && mStartActivity != topTaskActivity)) {
                // If the activity is not focusable, we can't resume it, but still would like to
                // make sure it becomes visible as it starts (this will also trigger entry
                // animation). An example of this are PIP activities.
                // Also, we don'
t want to resume activities in a task that currently has an overlay
                // as the starting activity just needs to be in the visible paused state until the
                // over is removed.
                // Passing {@code null} as the start parameter ensures all activities are made
                // visible.
                mTargetRootTask.ensureActivitiesVisible(null /* starting */,
                        0 /* configChanges */, !PRESERVE_WINDOWS);
                // Go ahead and tell window manager to execute app transition for this activity
                // since the app transition will not be triggered through the resume channel.
                mTargetRootTask.mDisplayContent.executeAppTransition();
            } else {
                // If the target root-task was not previously focusable (previous top running
                // activity on that root-task was not visible) then any prior calls to move the
                // root-task to the will not update the focused root-task.  If starting the new
                // activity now allows the task root-task to be focusable, then ensure that we
                // now update the focused root-task accordingly.
                //如果mTargetRootTask在mRootWindowContainer不处于focus状态,则调用mTargetRootTask.moveToFront方法把它设置为focus状态
                if (mTargetRootTask.isTopActivityFocusable()
                        && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
                    mTargetRootTask.moveToFront("startActivityInner");
                }
                //  开始进入下一步的启动Activity操作
                mRootWindowContainer.resumeFocusedTasksTopActivities(
                        mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
            }
        }
        
        省略代码......

        return START_SUCCESS;
    }

startActivityInner方法的逻辑相对复杂,下面先简要的分析下调用的几个方法做的事情:

  1. setInitialState方法 该方法主要对当前ActivityStarter的相关属性进行初始化,介绍下ActivityStarter的几个关键属性:

  • mStartActivity:代表正在启动的Activity,类型为ActivityRecord
  • mIntent:存放启动的其他信息
  • mCallingUid:启动者的uid
  • mSourceRecord:启动这,类型为ActivityRecord
  • mLaunchMode:启动模式
  • mLaunchFlags:启动的flags
  • mInTask:ActivityRecord放入的task
  • mNoAnimation:启动过程中是否有动画
  • mInTask:启动的Activity放入的task
  • computeLaunchingTaskFlags方法 该方法做的工作是设置mLaunchFlags,依据以下条件进行设置:

    1. 如果mSourceRecord为null并且mInTask为不null,在根据一些条件判断是否能使用mInTask(这个暂时不在这节的讨论范围)
    2. 如果不满足步骤1,则进入步骤2,把mInTask置为null
    3. 如果mInTask为null,则会有如下情况为mLaunchFlags增加FLAG_ACTIVITY_NEW_TASK 3.1. mSourceRecord为null(这种情况一般发生于比如在Service中或者Broadcast中启动Activity) 3.2. mSourceRecord启动者的启动模式是LAUNCH_SINGLE_INSTANCE(singleInstance启动模式代表Activity只能处于自己单独的task中) 3.3. 正在启动的Activity的mLaunchMode是LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK中的任意一个
  • computeSourceRootTask 该方法主要工作是获取mSourceRootTask,简单来介绍下rootTask和task,task不单单可以包含ActivityRecord,它还可以包含task,rootTask就是ActivityRecord的task的task的task等(直到task的parent不是task的时候就结束)

  • getReusableTask 这个方法的主要工作就是获取是否有可以重用的task,如果有则返回,否则返回null,大概的一个过程如下:

    1. putIntoExistingTask的值主要由 mInTask == null && mStartActivity.resultTo == null来决定,mInTask如果不为null,肯定不需要查找可重用的task了
    2. 如果putIntoExistingTask为true,则根据一些条件获取intentActivity
    3. 在根据一些条件决定intentActivity是否置为null
    4. 如果intentActivity不为null,则把它的task返回
  • computeTargetTask 该方法的主要工作是获取Activity可以放入的task,分以下条件获取:

    1. 根据mInTask,mLaunchFlags,mStartActivity.resultTo,mAddingToTask判断是否需要创建新task,是的话返回null
    2. mSourceRecord不为null的话,返回它的task
    3. mInTask不为null,则返回它
    4. 其他情况获取task

    startActivityInner方法主要做了以下事情:

    1. 根据一些条件来决定是创建一个新的task还是使用已有的task,并且把ActivityRecord放入task中
    2. 如果mDoResume为true,则最终会调用mRootWindowContainer.resumeFocusedTasksTopActivities方法进入下一步启动Activity的操作。

    调用mRootWindowContainer.resumeFocusedTasksTopActivities方法,来介绍下它的参数:

    • targetRootTask:Task类型,它的值是mTargetRootTask,正在启动的Activity对应的ActivityRecord已经放入了这个task内
    • ActivityRecord: ActivityRecord类型,它的值是mStartActivity(保存了正在启动的activity等信息)
    • targetOptions:ActivityOptions类型,它的值为null
    • deferPause:代表是否延迟pause top Activity,它的值为false(mTransientLaunch默认是false)

    2.6 RootWindowContainer#resumeFocusedTasksTopActivities

        boolean resumeFocusedTasksTopActivities(
                Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
                boolean deferPause) {
            if (!mTaskSupervisor.readyToResume()) {
                return false;
            }

            boolean result = false;
            //targetRootTask不为null并且targetRootTask是在DisplayArea中是最顶层的roottask,则进入下面逻辑
            if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
                    || getTopDisplayFocusedRootTask() == targetRootTask)) {
                [2.7]
                //targetOptions为null,deferPause为false
                result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
                        deferPause);
            }

            省略代码......

            return result;
        }

    2.7 Task#resumeTopActivityUncheckedLocked

        boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
                boolean deferPause) {
            //正在resume top,则直接返回
            if (mInResumeTopActivity) {
                // Don't even start recursing.
                return false;
            }

            boolean someActivityResumed = false;
            try {
                // Protect against recursion.
                mInResumeTopActivity = true;
                //当前的task是叶子task(就是task的孩子都是ActivityRecord),就执行下面逻辑(咱们分析这个流程)
                if (isLeafTask()) {
                    //task是否focus并且可见
                    if (isFocusableAndVisible()) {
                        [2.8]
                        //prev为正在启动的Activity对应的ActivityRecord,options:null,deferPause:false
                        someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
                    }
                } else {
                    //当前的task的孩子还是task,走下面逻辑
                    int idx = mChildren.size() - 1;
                    while (idx >= 0) {
                        final Task child = (Task) getChildAt(idx--);
                        if (!child.isTopActivityFocusable()) {
                            continue;
                        }
                        if (child.getVisibility(null /* starting */) != TASK_VISIBILITY_VISIBLE) {
                            break;
                        }

                        someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options,
                                deferPause);
                        // Doing so in order to prevent IndexOOB since hierarchy might changes while
                        // resuming activities, for example dismissing split-screen while starting
                        // non-resizeable activity.
                        if (idx >= mChildren.size()) {
                            idx = mChildren.size() - 1;
                        }
                    }
                }

                省略代码......
            } finally {
                mInResumeTopActivity = false;
            }

            return someActivityResumed;
        }

    2.8 Task#resumeTopActivityInnerLocked

        private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
                boolean deferPause) {
            if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
                // Not ready yet!
                return false;
            }

            // Find the next top-most activity to resume in this root task that is not finishing and is
            // focusable. If it is not focusable, we will fall into the case below to resume the
            // top activity in the next focusable task.
            //next代表当前task中已经显示的Activity
            ActivityRecord next = topRunningActivity(true /* focusableOnly */);

            省略代码......

            //deferPause的值为false
            boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
            //mResumedActivity代表当前task中已经显示的Activity,若不为null,说明在启动其他Activity的时候,需要让mResumedActivity进入pause状态
            if (mResumedActivity != null) {
                ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Pausing %s", mResumedActivity);
                //下面方法会让mResumedActivity进入pause状态,为启动新的Activity做准备
                pausing |= startPausingLocked(false /* uiSleeping */, next,
                        "resumeTopActivityInnerLocked");
            }
            //如果mResumedActivity正在处于pausing状态,进入下面的逻辑
            if (pausing) {
                ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivityLocked: Skip resume: need to"
                        + " start pausing");
                // At this point we want to put the upcoming activity's process
                // at the top of the LRU list, since we know we will be needing it
                // very soon and it would be a waste to let it get killed if it
                // happens to be sitting towards the end.
                //next.attachedToProcess()为true,代表next已经启动过了,则更新它的进程等信息
                if (next.attachedToProcess()) {
                    next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
                            true /* activityChange */, false /* updateOomAdj */,
                            false /* addPendingTopUid */);
                } else if (!next.isProcessRunning()) {
                    // Since the start-process is asynchronous, if we already know the process of next
                    // activity isn'
    t running, we can start the process earlier to save the time to wait
                    // for the current activity to be paused.
                    final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
                    //next.isProcessRunning()为false,代表启动的activity的进程还没被启动,乘mResumedActivity处于pausing的状态,去异步启动进程
                    mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
                            isTop ? "pre-top-activity" : "pre-activity");
                }
                if (lastResumed != null) {
                    lastResumed.setWillCloseOrEnterPip(true);
                }
                return true;
            } else if (mResumedActivity == next && next.isState(RESUMED)
                    && taskDisplayArea.allResumedActivitiesComplete()) {
                // It is possible for the activity to be resumed when we paused back stacks above if the
                // next activity doesn't have to wait for pause to complete.
                // So, nothing else to-do except:
                // Make sure we have executed any pending transitions, since there
                // should be nothing left to do at this point.
                executeAppTransition(options);
                ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Top activity resumed "
                        + "(dontWaitForPause) %s", next);
                return true;
            }

            省略代码......

            //next.attachedToProcess()为true,代表next已经启动过了,执行下面的逻辑,会把让Activity进入resume状态
            if (next.attachedToProcess()) {
                
                省略代码......

                try {
                    final ClientTransaction transaction =
                            ClientTransaction.obtain(next.app.getThread(), next.appToken);
                    // Deliver all pending results.
                    ArrayList<ResultInfo> a = next.results;
                    //a代表从上个Activity是否返回了一些数据
                    if (a != null) {
                        final int N = a.size();
                        if (!next.finishing && N > 0) {
                            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                                    "Delivering results to " + next + ": " + a);
                            //从上个Activity返回了数据,则给transaction add一个ActivityResultItem
                            transaction.addCallback(ActivityResultItem.obtain(a));
                        }
                    }


                    if (next.newIntents != null) {
                        //若存在newIntents,则add 一个NewIntentItem,这种情况针对的Activity的启动模式是singleTask,singleInstance,singleTop
                        transaction.addCallback(
                                NewIntentItem.obtain(next.newIntents, true /* resume */));
                    }

                    // Well the app will no longer be stopped.
                    // Clear app token stopped state in window manager if needed.
                    next.notifyAppResumed(next.stopped);

                    EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next),
                            next.getTask().mTaskId, next.shortComponentName);

                    mAtmService.getAppWarningsLocked().onResumeActivity(next);
                    next.app.setPendingUiCleanAndForceProcessStateUpTo(mAtmService.mTopProcessState);
                    next.abortAndClearOptionsAnimation();
                    
                    //通知Activity进入resume状态
                    transaction.setLifecycleStateRequest(
                            ResumeActivityItem.obtain(next.app.getReportedProcState(),
                                    dc.isNextTransitionForward()));
                    mAtmService.getLifecycleManager().scheduleTransaction(transaction);

                    ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Resumed %s", next);
                } catch (Exception e) {
                    省略代码......
                    return true;
                }

                省略代码......

            } else {
                省略代码......
                //Activity需要从onCreate方法开始执行
                mTaskSupervisor.startSpecificActivity(next, true, true);
            }

            return true;
        }

    resumeTopActivityInnerLocked方法的逻辑相对复杂,下面就来介绍下它主要做的事情:

    1. 如果正在显示的Activity(mResumedActivity)存在,则需要让它进入pause状态(最终会把这个消息通知到app对应的Activity)

    2. 如果正在显示的Activity已处于pausing状态,这时候需要分情况来处理: 2.1 若正在启动的Activity(next)之前已经启动过了,则需要更新它对应的进程状态 2.2 若正在启动的Activity的进程还没有启动,这时候异步启动进程的操作

      接着暂停启动Activity的操作,直接返回。那什么时候继续开始启动Activity呢?答案是:当mResumedActivity对应的app端的Activity完全的进入pause状态后,才会接着继续启动Activity。 并且可以借助等待pause完毕的这个时机,更新进程状态或者异步启动进程

    3. 如果正在启动的Activity(next)已经启动过了(next.attachedToProcess()这值为true),则会走下面逻辑: 3.1 若从上个Activity返回了数据,则把数据返回给app端的Activity(onActivityForResult方法会被调用) 3.2 若存在newIntents,则把intent返回给app端的Activity(onNewIntent方法会被调用),这种情况针对的Activity的启动模式是singleTask,singleInstance,singleTop

      通知app端Activity进入resume状态(onResume方法会被调用)

    4. 否则,调用mTaskSupervisor.startSpecificActivity正真进入Activity的启动流程

    2.9 ActivityTaskSupervisor#startSpecificActivity

        //r:正在启动的Activity,andResume:当前值为true,checkConfig:当前值true
        void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
            // Is this activity's application already running?
            final WindowProcessController wpc =
                    mService.getProcessController(r.processName, r.info.applicationInfo.uid);

            boolean knownToBeDead = false;
            //对应的app进程是否启动,启动则进入下面逻辑
            if (wpc != null && wpc.hasThread()) {
                try {
                    [2.10]
                    realStartActivityLocked(r, wpc, andResume, checkConfig);
                    return;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting activity "
                            + r.intent.getComponent().flattenToShortString(), e);
                }

                // If a dead object exception was thrown -- fall through to
                // restart the application.
                knownToBeDead = true;
            }

            r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
         
            final boolean isTop = andResume && r.isTopRunningActivity();
            //异步启动进程
            mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
        }

    2.10 ActivityTaskSupervisor#realStartActivityLocked

        //r:正在启动的Activity,proc:对应的进程,andResume:true,checkConfig:true
        boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
                boolean andResume, boolean checkConfig) throws RemoteException {

            if (!mRootWindowContainer.allPausedActivitiesComplete()) {
                // While there are activities pausing we skipping starting any new activities until
                // pauses are complete. NOTE: that we also do this for activities that are starting in
                // the paused state because they will first be resumed then paused on the client side.
                ProtoLog.v(WM_DEBUG_STATES,
                        "realStartActivityLocked: Skipping start of r=%s some activities pausing...",
                        r);
                return false;
            }

            final Task task = r.getTask();
            final Task rootTask = task.getRootTask();

            beginDeferResume();
            // The LaunchActivityItem also contains process configuration, so the configuration change
            // from WindowProcessController#setProcess can be deferred. The major reason is that if
            // the activity has FixedRotationAdjustments, it needs to be applied with configuration.
            // In general, this reduces a binder transaction if process configuration is changed.
            proc.pauseConfigurationDispatch();

            try {
                r.startFreezingScreenLocked(proc, 0);

                // schedule launch ticks to collect information about slow apps.
                r.startLaunchTickingLocked();
                //设置了proc后,r.attachedToProcess()的值就为true
                r.setProcess(proc);

                // Ensure activity is allowed to be resumed after process has set.
                if (andResume && !r.canResumeByCompat()) {
                    andResume = false;
                }

                省略代码......

                try {
                    //proc.hasThread()代表app端是否活着
                    if (!proc.hasThread()) {
                        throw new RemoteException();
                    }
                    List<ResultInfo> results = null;
                    List<ReferrerIntent> newIntents = null;
                    if (andResume) {
                        // We don't need to deliver new intents and/or set results if activity is going
                        // to pause immediately after launch.
                        results = r.results;
                        newIntents = r.newIntents;
                    }
                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                            "Launching: " + r + " savedState=" + r.getSavedState()
                                    + " with results=" + results + " newIntents=" + newIntents
                                    + " andResume=" + andResume);
                    EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),
                            task.mTaskId, r.shortComponentName);
                    if (r.isActivityTypeHome()) {
                        // Home process is the root process of the task.
                        updateHomeProcess(task.getBottomMostActivity().app);
                    }
                    mService.getPackageManagerInternalLocked().notifyPackageUse(
                            r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY);
                    r.forceNewConfig = false;
                    mService.getAppWarningsLocked().onStartActivity(r);
                    r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);

                    // Because we could be starting an Activity in the system process this may not go
                    // across a Binder interface which would create a new Configuration. Consequently
                    // we have to always create a new Configuration here.
                    final Configuration procConfig = proc.prepareConfigurationForLaunchingActivity();
                    final MergedConfiguration mergedConfiguration = new MergedConfiguration(
                            procConfig, r.getMergedOverrideConfiguration());
                    r.setLastReportedConfiguration(mergedConfiguration);

                    logIfTransactionTooLarge(r.intent, r.getSavedState());

                    if (r.isEmbedded()) {
                        // Sending TaskFragmentInfo to client to ensure the info is updated before
                        // the activity creation.
                        mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
                                r.getOrganizedTaskFragment());
                    }

                    // Create activity launch transaction.
                    //ClientTransaction主要用于添加各种callback以及Activity要执行的生命周期方法,它会通过binder传递到app进程
                    //proc.getThread()获取的是IApplicationThread的实例,主要通过它给app发送消息,r.appToken发送给app的token
                    final ClientTransaction clientTransaction = ClientTransaction.obtain(
                            proc.getThread(), r.appToken);

                    final boolean isTransitionForward = r.isTransitionForward();
                    //add一个LaunchActivityItem类型的callback
                    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                            System.identityHashCode(r), r.info,
                            // TODO: Have this take the merged configuration instead of separate global
                            // and override configs.
                            mergedConfiguration.getGlobalConfiguration(),
                            mergedConfiguration.getOverrideConfiguration(), r.compat,
                            r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
                            proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
                            results, newIntents, r.takeOptions(), isTransitionForward,
                            proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                            r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
                            r.getLaunchedFromBubble()));

                    // Set desired final state.
                    final ActivityLifecycleItem lifecycleItem;
                    if (andResume) {
                        //因为andResume为true,进入这,构造一个ResumeActivityItem实例,Activity的onResume方法被执行
                        lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
                    } else {
                        //否则构造一个PauseActivityItem实例,Activity的onPause方法会被执行
                        lifecycleItem = PauseActivityItem.obtain();
                    }
                    clientTransaction.setLifecycleStateRequest(lifecycleItem);

                    // Schedule transaction.
                    //clientTransaction会被传递到app进程
                    mService.getLifecycleManager().scheduleTransaction(clientTransaction);

                    省略代码......

                } catch (RemoteException e) {
                    省略代码......
                }
            } finally {
                endDeferResume();
                proc.resumeConfigurationDispatch();
            }

            r.launchFailed = false;

            省略代码......

            return true;
        }

    该方法主要做的事情是把各种数据整理收集好后,通过binder发送到app进程,那就来看下这个过程:

    1.获取一个ClientTransaction实例通过ClientTransaction.obtain方法获取一个ClientTransaction实例,为了避免浪费内存从缓存池中获取,ClientTransaction代表要传递给app的事务,它可以包含多个callback和一个lifecycleStateRequest。 来介绍下ClientTransaction.obtain这个方法它的参数:

    • client:IApplicationThread类型,AMS通过它把消息发送给app,它的值是proc.getThread()
    • activityToken:IBinder类型,它的值是r.appToken。AMS并没有把ActiviityRecord传递给app(传过去不安全),而是把ActiviityRecord的appToken传递过去,简单看下这个appToken,它的代码如下:
    public final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {

        final ActivityRecord.Token appToken;

        static class Token extends IApplicationToken.Stub {
            private WeakReference<ActivityRecord> weakActivity;
            private final String name;
            private final String tokenString;

            Token(Intent intent) {
                name = intent.getComponent().flattenToShortString();
                tokenString = "Token{" + Integer.toHexString(System.identityHashCode(this)) + "}";
            }

            //attach到ActivityRecord,这样就持有它了
            private void attach(ActivityRecord activity) {
                if (weakActivity != null) {
                    throw new IllegalStateException("Already attached..." + this);
                }
                weakActivity = new WeakReference<>(activity);
            }

            //根据token来拿到ActivityRecord
            private static @Nullable ActivityRecord tokenToActivityRecordLocked(Token token) {
                if (token == null) {
                    return null;
                }
                ActivityRecord r = token.weakActivity.get();
                //r.getRootTask()为null,代表它也是个”废物“了
                if (r == null || r.getRootTask() == null) {
                    return null;
                }
                return r;
            }

            @Override
            public String toString() {
                StringBuilder sb = new StringBuilder(128);
                sb.append("Token{");
                sb.append(Integer.toHexString(System.identityHashCode(this)));
                sb.append(' ');
                if (weakActivity != null) {
                    sb.append(weakActivity.get());
                }
                sb.append('}');
                return sb.toString();
            }

            @Override
            public String getName() {
                return name;
            }
        }
    }

    ActivityRecord的appToken是一个类型为Token的实例。Token它继承了IApplicationToken.Stub说明它是一个IBinder类型,它用弱引用的方式持有ActivityRecord,appToken作为一个“令牌”被传递到app进程,就是告诉app,我给了你一个token,如果想给我发送消息,就带上这个token,我就能通过token找到ActivityRecord了(tokenToActivityRecordLocked方法)

    Token这个类作为一个binder服务给使用者就提供了一个getName()方法,因此可以看出它在app端完全就是当作“令牌”来使用或者当作ActivityRecord的唯一标识来使用。

    2.获取LaunchActivityItem实例通过LaunchActivityItem.obtain方法获取实例,同样也为了效率和避免浪费内存,LaunchActivityItem也从缓冲池中获取,这个类包含了启动一个Activity的所有信息,来介绍下它的关键的属性:

    • intent:启动时候的intent(包含传递给Activity的数据等等),最终会被传递到“终点”
    • info:ActivityInfo类型,这个属性非常重要,它包含了app端具体Activity的类名,包名等信息
    • curConfig:Configuration类型,配置信息
    • state:Bundle类型,代表Activity在AMS中保存的信息,它会被传递给onCreate方法

    会调用第一步ClientTransaction的addCallback方法加入LaunchActivityItem实例

    3. 获取ResumeActivityItem实例ResumeActivityItem代表需要执行Activity的onResume方法,会调用clientTransaction.setLifecycleStateRequest(lifecycleItem)

    4. 最后把clientTransaction发送给app调用mService.getLifecycleManager().scheduleTransaction(clientTransaction)方法把clientTransaction发送到app端

    小结

    用一张时序图进行小结

    3. app接收并处理AMS发出的信息

    AMS把clientTransaction发送到app端,因为**mService.getLifecycleManager().scheduleTransaction(clientTransaction)方法最终执行的代码是mClient.scheduleTransaction(clientTransaction)**(mClient是IApplicationThread类型)这是一个binder调用,mClient对应的是app进程的ActivityThread$ApplicationThread类型实例 ,因此最终会进入ApplicationThread的scheduleTransaction方法

    3.1 ApplicationThread#scheduleTransaction

        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

    3.2 ActivityThread#scheduleTransaction

        public abstract class ClientTransactionHandler {

            /** Prepare and schedule transaction for execution. */
            void scheduleTransaction(ClientTransaction transaction) {
                transaction.preExecute(this);
                sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
            }
        }

    ActivityThread继承了ClientTransactionHandler,关于clientTransaction是如何分发的流程在这节中不介绍了,经过分发后会进入LaunchActivityItem的execute方法

    #### 3.3 LaunchActivityItem#execute

        @Override
        public void execute(ClientTransactionHandler client, IBinder token,
                            PendingTransactionActions pendingActions) {
            Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                    mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                    mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
                    client, mAssistToken, mFixedRotationAdjustments, mShareableActivityToken,
                    mLaunchedFromBubble, mTaskFragmentToken);
            //ActivityThread继承了ClientTransactionHandler,最终进入它的对应方法
            [3.4]
            client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }

    该方法,把AMS传递过来的参数放置在了ActivityClientRecord的实例中,还记得AMS中记录Activity的类是ActivityRecord吧,它俩是一一对应的。ActivityClientRecord

        /** Activity client record, used for bookkeeping for the real {@link Activity} instance. */
        public static final class ActivityClientRecord {
            //tokenAMS传递过来的令牌
            @UnsupportedAppUsage
            public IBinder token;
            
            省略属性......

            @UnsupportedAppUsage
            Intent intent;
            String referrer;
            IVoiceInteractor voiceInteractor;
            //AMS传递过来的保存的数据
            Bundle state;
            PersistableBundle persistentState;
            //app端真正启动的Activity实例
            @UnsupportedAppUsage
            Activity activity;
            //Activity对应的window
            Window window;
            Activity parent;
            String embeddedID;
            Activity.NonConfigurationInstances lastNonConfigurationInstances;
            // TODO(lifecycler): Use mLifecycleState instead.

            //是否paused
            @UnsupportedAppUsage
            boolean paused;
            //是否stoped
            @UnsupportedAppUsage
            boolean stopped;
            boolean hideForNow;

            //config信息
            Configuration createdConfig;
            Configuration overrideConfig;
            
            省略属性......

            //AMS传递过来的activityinfo信息
            @UnsupportedAppUsage
            ActivityInfo activityInfo;
            @UnsupportedAppUsage
            CompatibilityInfo compatInfo;
            @UnsupportedAppUsage
            public LoadedApk packageInfo;

            省略属性......

            //生命周期状态值
            @LifecycleState
            private int mLifecycleState = PRE_ON_CREATE;
        }

    ActivityClientRecord不单单包含了AMS传递过来的信息,还包含app端真正启动的Activity实例以及对应的生命周期状态

    3.4 ActivityThread#handleLaunchActivity

        @Override
        public Activity handleLaunchActivity(ActivityClientRecord r,
                PendingTransactionActions pendingActions, Intent customIntent) {
            省略代码......

            WindowManagerGlobal.initialize();

            // Hint the GraphicsEnvironment that an activity is launching on the process.
            GraphicsEnvironment.hintActivityLaunch();

            //开始启动Activity
            [3.5]
            final Activity a = performLaunchActivity(r, customIntent);

            省略代码......

            return a;
        }

    3.5 ActivityThread#performLaunchActivity

        private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
            ActivityInfo aInfo = r.activityInfo;
            if (r.packageInfo == null) {
                r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                        Context.CONTEXT_INCLUDE_CODE);
            }

            //ComponentName封装了mPackage和mClass,component是真正Activity的对应的信息,先从r.intent.getComponent()获取
            ComponentName component = r.intent.getComponent();
            if (component == null) {
                //没获取到从PMS中去解析
                component = r.intent.resolveActivity(
                    mInitialApplication.getPackageManager());
                r.intent.setComponent(component);
            }

            //如果targetActivity存在,则从targetActivity获取
            if (r.activityInfo.targetActivity != null) {
                component = new ComponentName(r.activityInfo.packageName,
                        r.activityInfo.targetActivity);
            }

            //初始化appContext它的类型是ContextImpl,像Activity调用到的Context的方法最终都是通过ContextImpl来实现的
            ContextImpl appContext = createBaseContextForActivity(r);
            Activity activity = null;
            try {
                //获取ClassLoader,来加载Activity
                java.lang.ClassLoader cl = appContext.getClassLoader();
                //mInstrumentation.newActivity方法中通过反射来实例化一个Activity
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                StrictMode.incrementExpectedActivityCount(activity.getClass());
                r.intent.setExtrasClassLoader(cl);
                r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
                        appContext.getAttributionSource());
                if (r.state != null) {
                    r.state.setClassLoader(cl);
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(activity, e)) {
                    throw new RuntimeException(
                        "Unable to instantiate activity " + component
                        + ": " + e.toString(), e);
                }
            }

            try {
                //尝试去make Application(一般情况下都已经创建成功了),如果存在直接返回
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);

                if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
                if (localLOGV) Slog.v(
                        TAG, r + ": app=" + app
                        + ", appName=" + app.getPackageName()
                        + ", pkg=" + r.packageInfo.getPackageName()
                        + ", comp=" + r.intent.getComponent().toShortString()
                        + ", dir=" + r.packageInfo.getAppDir());

                if (activity != null) {
                    CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                    Configuration config =
                            new Configuration(mConfigurationController.getCompatConfiguration());
                    if (r.overrideConfig != null) {
                        config.updateFrom(r.overrideConfig);
                    }
                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                            + r.activityInfo.name + " with config " + config);
                    Window window = null;
                    if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                        window = r.mPendingRemoveWindow;
                        r.mPendingRemoveWindow = null;
                        r.mPendingRemoveWindowManager = null;
                    }

                    // Activity resources must be initialized with the same loaders as the
                    // application context.
                    appContext.getResources().addLoaders(
                            app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

                    appContext.setOuterContext(activity);

                    //attach方法把各种数据传递给activity
                    activity.attach(appContext, this, getInstrumentation(), r.token,
                            r.ident, app, r.intent, r.activityInfo, title, r.parent,
                            r.embeddedID, r.lastNonConfigurationInstances, config,
                            r.referrer, r.voiceInteractor, window, r.configCallback,
                            r.assistToken, r.shareableActivityToken);

                    if (customIntent != null) {
                        activity.mIntent = customIntent;
                    }
                    r.lastNonConfigurationInstances = null;
                    checkAndBlockForNetworkAccess();
                    activity.mStartedActivity = false;
                    int theme = r.activityInfo.getThemeResource();
                    if (theme != 0) {
                        activity.setTheme(theme);
                    }

                    if (r.mActivityOptions != null) {
                        activity.mPendingOptions = r.mActivityOptions;
                        r.mActivityOptions = null;
                    }
                    activity.mLaunchedFromBubble = r.mLaunchedFromBubble;
                    activity.mCalled = false;

                    //下面是根据r.isPersistable(),分别调用Activity的onCreate方法
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }

                    //如果自己实现的Activity的onCreate方法没有调用父类的onCreate方法,则抛异常
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onCreate()");
                    }
                    r.activity = activity;
                    mLastReportedWindowingMode.put(activity.getActivityToken(),
                            config.windowConfiguration.getWindowingMode());
                }
                r.setState(ON_CREATE);

                // updatePendingActivityConfiguration() reads from mActivities to update
                // ActivityClientRecord which runs in a different thread. Protect modifications to
                // mActivities to avoid race.
                synchronized (mResourcesManager) {
                    //AMS传递过来的token作为key,r作为value存放在mActivities中
                    mActivities.put(r.token, r);
                }

            } catch (SuperNotCalledException e) {
                throw e;

            } catch (Exception e) {
                if (!mInstrumentation.onException(activity, e)) {
                    throw new RuntimeException(
                        "Unable to start activity " + component
                        + ": " + e.toString(), e);
                }
            }

            return activity;
        }

    该方法是启动Activity的核心方法主要做了以下几件事:

    1. 获取到ComponentName,它包含了真正Activity的包名,class信息
    2. 使用ClassLoader,通过反射对第1步的类进行实例化,会实例化一个Activity
    3. 尝试创建/获取Application的实例
    4. 通过Activity的attach方法把各种信息传递给它
    5. 调用Activity的onCreate方法
    6. AMS传递过来的token作为key,r作为value存放在mActivities中(这样通过tokenActivityRecord和ActivityClientRecord就建立了关系)

    最后分析下mInstrumentation.callActivityOnCreate这个方法

    3.6 Instrumentation#callActivityOnCreate

        public void callActivityOnCreate(Activity activity, Bundle icicle) {
            prePerformCreate(activity);
            [3.7]
            activity.performCreate(icicle);
            postPerformCreate(activity);
        }

    3.7 Activity#performCreate

        final void performCreate(Bundle icicle) {
            performCreate(icicle, null);
        }

        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        final void performCreate(Bundle icicle, PersistableBundle persistentState) {
            if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
                Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performCreate:"
                        + mComponent.getClassName());
            }
            dispatchActivityPreCreated(icicle);
            mCanEnterPictureInPicture = true;
            // initialize mIsInMultiWindowMode and mIsInPictureInPictureMode before onCreate
            final int windowingMode = getResources().getConfiguration().windowConfiguration
                    .getWindowingMode();
            mIsInMultiWindowMode = inMultiWindowMode(windowingMode);
            mIsInPictureInPictureMode = windowingMode == WINDOWING_MODE_PINNED;
            restoreHasCurrentPermissionRequest(icicle);

            //onCreate方法被调用
            if (persistentState != null) {
                onCreate(icicle, persistentState);
            } else {
                onCreate(icicle);
            }
            EventLogTags.writeWmOnCreateCalled(mIdent, getComponentName().getClassName(),
                    "performCreate");
            mActivityTransitionState.readState(icicle);

            mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                    com.android.internal.R.styleable.Window_windowNoDisplay, false);
            mFragments.dispatchActivityCreated();
            mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
            dispatchActivityPostCreated(icicle);
            

    到此Activity的onCreate方法被调用,因为clientTransaction.setLifecycleStateRequest(lifecycleItem),lifecycleItem是ResumeActivityItem类型,Activity的onResume方法也会被调用,这个流程就不分析了.

    小结

    同样用一张时序图小结

    总结

    Activity启动源码分析的整个过程就结束了,更多的总结内容可以看上面的原理.

    思考

    为啥启动Activity必须要经过AMS?想当年作为android新手的时候,认为app启动其他app内的Activity的时候经过AMS可以理解,毕竟app进程之间是不可以直接通信的,需要经过系统进程的AMS进行"中转".但是app启动自己内部的Activity的时候为啥也要经过AMS,经过AMS启动速度的话会慢,这里的慢是相对不经过AMS直接在app内启动的这样的假设.为啥会慢呢,如上面的分析流程,启动Activity需要在进程之间进行两次通信,Intent等数据也需要在进程之间传递来传递去的.

    造成上面这种错误认识的原因是当时我只是把AMS认为只是起一个"中转"的功能.其实不是这样的,AMS的功能并非如此简单,AMS管理着所有的Activity(当然还管理着其他的三大组件),哪个Activity应该进入resume状态了,哪个应该进入pause或者stop状态,哪个应该进入destory状态等等生命周期状态的切换都是AMS来统一的协调处理;还有比如用户修改了系统的字体或者别的设置信息,那都需要AMS去通知Activity是否需要重新启动以来适配新的设置变化等等.

    所以启动的目标Activity不管是app内的还是其他app的都需要去AMS,进行查询,检查,校验,记录流程,只有记录成功后,Activity启动才算在AMS环节成功了,AMS会通过记录下来的Activity信息进而来控制Activity的生命周期状态的切换.

    AMS就是要管理控制Activity,如果没有它,那app内的Activity“各自为政”那岂不是乱套了。

    再谈Token如果做过web相关的开发,大家应该都了解,在用户登录后,服务器会返回给客户端一些信息,其中就有token,这个token它是一个字符串,并且是整个系统内唯一的.以后客户端与服务器进行通信就需要携带上这个token,服务器就知道到底是哪个用户在与之进行交互.

    在启动Activity时候,AMS会返回一个Token类型的token实例给app进程,这里的token和web开发相关的token作用是一样的. AMS把这个token传递给app,app端也会把启动的Activity记录在本地的ActivityClientRecord类中,这个类中会记录下"真正启动的Activity的引用".app端会把token作为key值,ActivityClientRecord作为value值保存起来.ActivityRecord与ActivityClientRecord就通过token建立了联系.

    AMS通知某个Activity进入某种生命周期状态,会把token值传递给app端,app端收到这个命令后,会通过这个token拿到ActivityClientRecord进而拿到真正启动的Activity的引用,进而调用它的对应回调方法.

    app端某个Activity完成了某个操作后(比如pause操作),会携带token等其他信息通知AMS(因为token是一个IBinder类型,它进入AMS后会被转化为Binder),AMS通过token拿到对应的ActivityRecord,进而调用它相应的方法.

    为啥要传递一个IBinder类型的token?假如传递一个int类型或者String类型的token是不是也可行,当然是可行的,但是有一个问题就是复杂度要比使用IBinder类型高,复杂度高主要是体现在AMS. 原因是这样的:为了维护token与ActivityRecord之间建立一一对应关系可以使用有两种方式:其一token作为key值ActivityRecord作为value存储起来;其二每个ActivityRecord增加一个属性用来存储token. 这两种方式成本都挺高:其一方式使用的内存会多,并且维护成本也高,ActivityRecord的删除,增加,修改都需要去更新相应的存储容器;其二方式虽然不需要增加内存,但是多了查找成本,每次都需要从容器中拿出ActivityRecord依次进行对比.

    那来看看IBinder类型的token是怎么解决上面的问题的.首先Token类([2.10]的代码)通过弱引用的方式持有ActivityRecord,这样也不会有内存泄漏的问题,在AMS端构造的token实例肯定是系统内唯一的,因为它是在系统进程中初始化完毕分发给其他进程使用的.

    token传递到app进程后它会被转换为BinderProxy类型,并且binder机制是保证一个进程内的同一IBinder类型实例是仅存在一份的,意思就是即使AMS多次发送同一个Binder实例给进程,在这个进程内的BinderProxy类型的实例也是只有一个.在进程内可以通过使用"=="来比较两个token是否是一样的,这和使用int类型或者String类型的token也没有区别,更重要的是这种类型的token扩展性好,比如Token增加一些接口的话,其他进程内是可以使用的.

    当app进程传递token到AMS后,token会被转换为Binder类型,这时候的token已经是Token了,直接可以通过它找到ActivityRecord.

    IBinder类型的token复杂度也低,扩展性也好,这就是要使用IBinder类型的token的原因.


    继续滑动看下一个
    牛晓伟
    向上滑动看下一个

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存