Activity启动流程分析二 解析Activity启动参数

ATMS的Activity启动入口 startActivityAsUser

Instrumentation执行startActivity后,会来到ATMS的startActivityAsUser方法

 ActivityStartController getActivityStartController() {
        return mActivityStartController;
    }
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) {
        ......
        // TODO: Switch to user app stacks here.
        //通过ActivityStartController去获取一个ActivityStarter
        return 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();

    }

ActivityStartController和ActivityStarter

这里出现了两个类ActivityStartController和ActivityStarter
ActivityStarter用于去解析Activity启动的参数,每一个Activity启动的时候都对应着一个ActivityStarter去解析它的参数。在ActivityStarter中包含了一个静态内部类Request,这个类或许非常恰当的说明ActivityStarter的作用。它的部分代码如下:

static class Request {
...
IApplicationThread caller;//我们的App的Binder,也代表着谁来调用我们的启动流程
Intent intent;
NeededUriGrants intentGrants;
// A copy of the original requested intent, in case for ephemeral app launch.
Intent ephemeralIntent;
String resolvedType;
ActivityInfo activityInfo;
ResolveInfo resolveInfo;
IVoiceInteractionSession voiceSession;
IVoiceInteractor voiceInteractor;
IBinder resultTo;
String resultWho;
int requestCode;//activity启动的返回结果
int callingPid = DEFAULT_CALLING_PID;
int callingUid = DEFAULT_CALLING_UID;
String callingPackage;
@Nullable String callingFeatureId;
int realCallingPid = DEFAULT_REAL_CALLING_PID;
int realCallingUid = DEFAULT_REAL_CALLING_UID;
int startFlags;
SafeActivityOptions activityOptions;
boolean ignoreTargetSecurity;
boolean componentSpecified;
boolean avoidMoveToFront;
ActivityRecord[] outActivity;
Task inTask;
String reason;
ProfilerInfo profilerInfo;
Configuration globalConfig;
int userId;
WaitResult waitResult;
int filterCallingUid;
PendingIntentRecord originatingPendingIntent;
boolean allowBackgroundActivityStart;
...
}

ActivityStartController是ActivityStarter的控制器,它控制着ActivityStarter的创建。在ATMS的init函数初始化,辅助ATMS去创建和管理ActivityStarter。

 //ActivityStartController的obtainStarter方法
ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }

//在ActivityStarter静态内部类DefaultFactory 
//在ActivityStartController构造函数里面被创建
static class DefaultFactory implements Factory {
        /**
         * The maximum count of starters that should be active at one time:
         * 1. last ran starter (for logging and post activity processing)
         * 2. current running starter
         * 3. starter from re-entry in (2)
         */
        private final int MAX_STARTER_COUNT = 3;

        private ActivityStartController mController;
        private ActivityTaskManagerService mService;
        private ActivityStackSupervisor mSupervisor;
        private ActivityStartInterceptor mInterceptor;

        private SynchronizedPool<ActivityStarter> mStarterPool =
                new SynchronizedPool<>(MAX_STARTER_COUNT);

        DefaultFactory(ActivityTaskManagerService service,
                ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
            mService = service;
            mSupervisor = supervisor;
            mInterceptor = interceptor;
        }

        @Override
        public void setController(ActivityStartController controller) {
            mController = controller;
        }

        @Override
        public ActivityStarter obtain() {
            ActivityStarter starter = mStarterPool.acquire();

            if (starter == null) {
                starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
            }

            return starter;
        }

        @Override
        public void recycle(ActivityStarter starter) {
            starter.reset(true /* clearRequest*/);
            mStarterPool.release(starter);
        }
    }

ActivityStartController创建ActivityStarter使用了享元设计模式

可以看到ActivityStartController创建ActivityStarter使用了享元设计模式,减少了内部抖动。每启动一个Activity都需要创建一个ActivityStarter 去解析Activity启动参数,这边设计了一个大小为3的缓存池,当ActivityStarter 使用完成后,初始化所有数据后放到池子里面,下一次不需要new出ActivityStarter,直接从池子里面拿就行了。

ActivityStarter的executeRequest创建Activity的实例 ActivityRecord对象,启动那些需要启动,但是一直没有来得及启动的Activitys,最后启动我们目标activity

通过ActivityStartController创建ActivityStarter,并且在ActivityStarter的Request里面保存下来相应的参数后,接下来执行ActivityStart的execute函数,execute会执行executeRequest函数

 private int executeRequest(Request request) {
        //拿出Request记录的Activity的相关参数
        //检测判断这些参数是否合规
        ......
        //创建出我们的目标 ActivityRecord对象,存到传入数组0索引上
        //这一步已经创建出Activity的实例,Activty在Frameworks层就叫做ActivityRecord
        final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, callingFeatureId, intent, resolvedType, aInfo,
                mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
                request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
                sourceRecord);
         ......
		 // 启动那些需要启动,但是一直没有来得及启动的Activitys
		 // 比如说一个屏幕里面同时存在两个Activity,,最后也是调用startActivityUnchecked启动activity
        mController.doPendingActivityLaunches(false); 
         //启动最后需要启动的activity,也就是当前activity
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);
       ......
        return mLastStartActivityResult;
    }

executeRequest函数里面先拿出Request记录的Activity的相关参数,检测判断这些参数是否合规。接着创建出我们的目标 ActivityRecord对象,存到传入数组0索引上。这一步已经创建出Activity的实例,Activty在Frameworks层就叫做ActivityRecord。接下来启动那些需要启动,但是一直没有来得及启动的Activitys,比如说一个屏幕里面两个Activity。最后才是启动我们目标activity。

startActivityInner方法里面初始化配置,计算要启动的Activty的栈和源Activity所在的栈,然后将启动模式塞到mIntent里面。在把启动流程交给RootWindowContainer之前,创建了一个黑白屏window

我们调用startActivityUnchecked方法启动目标activity的时候,会跑到startActivityInner方法里面。

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        //初始化配置,mStartActivity、mLaunchMode等
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor, restrictedBgActivity);

         // 计算要启动的Activity的task标志,也就是计算启动模式
        computeLaunchingTaskFlags();

        //计算源Activity所在的Stack
        computeSourceStack();

        //将mLaunchFlags设置给Intent,也就是设置启动模式
        mIntent.setFlags(mLaunchFlags);

        ......
        // 创建启动黑白屏window
        mTargetStack.startActivityLocked(mStartActivity,
                topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask,
                mKeepCurTransition, mOptions);
               ......
               //把我们的启动流程交给RootWindowContainer
                mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
        
       ......
    }

在startActivityInner方法里面初始化配置,计算要启动的Activty的栈和源Activity所在的栈,然后将启动模式塞到mIntent里面。在把启动流程交给RootWindowContainer之前,创建了一个黑白屏window,这是为什么呢?

为什么创建了一个黑白屏window

因为如果是从Launcher程序启动我们的App的mainActivty的话,启动流程执行到这里,App进程是还没有被创建的。我们在ActivityStackSupervior类里面才去判断App进程是否存在,不存在则通过ZygoteProcess给ZygoteService发送一个socket信息,ZygoteService收到socket信息才会fork出我们的app进程。这是一个缓慢的过程。如果不弄一个黑白屏幕去相应用户的点击事件,用户点击后往往要几秒钟才会启动MainActivity,用户会以为没有点击到图标,可能会疯狂点击。

为什么要交给RootWindowContainer去执行接下来的启动流程

我们的启动流程在ActivityStartController创建ActivityStarter,ActivityStarter解析相应的参数,并且计算好要启动的Activity栈信息,源Activty的栈信息,启动一个黑白屏后,为什么要交给RootWindowContainer去执行接下来的启动流程?

RootWindowContainer是窗口容器(WindowContainer)的根容器,管理了所有窗口容器,设备上所有的窗口(Window)、显示(Display)都是由它来管理的。窗口又是需要依赖Activity存在的,基于这层关系,我猜测设计的时候干脆把Activty启动流程的一些步骤交给RootWindowContainer。

你可能感兴趣的:(FrameWork,android,jvm,开发语言,java,前端,html)