美文网首页
Activity启动流程分析

Activity启动流程分析

作者: Horps | 来源:发表于2022-12-21 10:03 被阅读0次
  • 概述

    本文分析Activity在FrameWork层的启动流程,基于API29源码进行分析。

    不管是在Launcher启动还是程序内自写代码的启动,最终都是通过startActivity方法开启Activty启动流程,startActivity方法又有通过ContextImpl和Activity两种方式实现,前者是通过ActivityThread的Instrumentation实现,后者是通过Activity的Instrumentation实现,其实都是同一个Instrumentation,只不过这个Instrumentation实例是在Activity的启动过程中创建的,如果我们要找一个开始,那就是系统启动Launcher的时候会创建一个Instrumentation,而一切都是从它的execStartActivity方法开始的。

  • Instrumentation的execStartActivity方法

    Instrumentation的意思是仪表盘,意味着它是启动的外在控制接口。

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
          ...
        try {
            ...
            int result = ActivityTaskManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
              //启动结果会以int的形式返回,这里检查各种异常
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
    

    这里调用了ActivityTaskManager.getService():

    public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }
    
    @UnsupportedAppUsage(trackingBug = 129726065)
    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                    return IActivityTaskManager.Stub.asInterface(b);
                }
            };
    

    从这里通过Binder开始进入了进程间调用,获取的是IActivityTaskManager类型实例,它的实现类是ActivityTaskManagerService。

  • ActivityTaskManagerService的startActivityAsUser方法

    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) {
        enforceNotIsolatedCaller("startActivityAsUser");
    
        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    
        // TODO: Switch to user app stacks here.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();
    
    }
    

    startActivity最终会调用到startActivityAsUser方法,getActivityStartController方法获取一个ActivityStartController对象,它在ActivityTaskManagerService初始化(initialize方法)的时候创建,它的obtainStarter方法如下:

    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }
    

    这个mFactory是在构造时传入的ActivityStarter.DefaultFactory:

    @Override
    public ActivityStarter obtain() {
        ActivityStarter starter = mStarterPool.acquire();
    
        if (starter == null) {
            starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
        }
    
        return starter;
    }
    

    可见obtainStarter返回的就是ActivityStarter。

  • ActivityStarter

    ActivityStarter对象进行的一系列的set调用把信息都封装到了一个ActivityStarter.Request对象中,然后调用execute方法:

    int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                        mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup,
                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
            } else {
                return startActivity(mRequest.caller, ...);
            }
        } finally {
            onExecutionComplete();
        }
    }
    

    因为调用了setMayWait方法,这个方法里会设置mRequest.mayWait为true,表示是否等待Activity的启动结果,因此这里会走到startActivityMayWait方法,其内部又调用了:

    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, originatingPendingIntent,
            allowBackgroundActivityStart);
    

    startActivity方法有一系列重载,在最后一个startActivity中:

    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity, boolean restrictedBgActivity) {
        int result = START_CANCELED;
        final ActivityStack startedActivityStack;
        try {
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
        } finally {
              ...
            if (ActivityManager.isStartResultSuccessful(result)) {
                if (startedActivityStack != null) {
                    // we have to update the configuration for changing to different display.
                    final ActivityRecord currentTop =
                            startedActivityStack.topRunningActivityLocked();
                    if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
                        mRootActivityContainer.ensureVisibilityAndConfig(
                                currentTop, currentTop.getDisplayId(),
                                true /* markFrozenIfConfigChanged */, false /* deferResume */);
                    }
                }
            } else{...}
            mService.mWindowManager.continueSurfaceLayout();
        }
        postStartActivityProcessing(r, result, startedActivityStack);
        return result;
    }
    

    可以看到,这里调用了startActivityUnchecked方法继续启动:

    //创建或者获取要启动的Activity所附属的ActivityTask
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        newTask = true;
        result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
    } else if (mSourceRecord != null) {
        result = setTaskFromSourceRecord();
    } else if (mInTask != null) {
        result = setTaskFromInTask();
    } else {
        result = setTaskToCurrentTopOrCreateNewTask();
    }
    
    if (mDoResume) {
        if (!mTargetStack.isFocusable()
                || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                && mStartActivity != topTaskActivity)) {
            if (mTargetStack.isFocusable()
                    && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
            }
            mRootActivityContainer.resumeFocusedStacksTopActivities(
                    mTargetStack, mStartActivity, mOptions);
        }
    } 
    

    mDoResume在前面startActivity方法入口时传入的是true,mTargetStack是前面获取的要启动的Activity所属的Task,如果不在前台则调用moveToFront方法将其移到前台,然后调用mRootActivityContainer的resumeFocusedStacksTopActivities方法:

    boolean resumeFocusedStacksTopActivities(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
          ...
        boolean result = false;
        if (targetStack != null && (targetStack.isTopStackOnDisplay()
                || getTopDisplayFocusedStack() == targetStack)) {
            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
          ...
    }
    

    resumeTopActivityUncheckedLocked方法如下:

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
          ...
        boolean result = false;
        try {
            // Protect against recursion.
            mInResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
              ...
        }...
        return result;
    }
    

    这里又调用了resumeTopActivityInnerLocked方法:

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
          ...
          ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
          ...
        if (next.attachedToProcess()) {
              ...
        }else{
              ...
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
          return true;
    }
    

    此时的attachedToProcess会返回false,因为此时还没和process绑定,所以会走到ActivityStackSupervisor的startSpecificActivityLocked方法:

    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);
          ...
        //如果Activity所需的进程已启动
        if (wpc != null && wpc.hasThread()) {
            try {
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } ...
        ...
          try {
            ...
            //如果是需要启动新进程
            final Message msg = PooledLambda.obtainMessage(
                  ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                        r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
                mService.mH.sendMessage(msg);
        }...
    }
    

    这里会根据mService.getProcessController是否能取到WindowProcessController来判断是否需要新建进程启动,getProcessController方法内是根据ActivityInfo的processName保存的WindowProcessController,因此我们回到创建ActivityInfo的地方看看这个processName是什么。

    ActivityInfo在ActivityStackSupervisor的resolveIntent方法中通过mService.getPackageManagerInternalLocked().resolveIntent方法生成的:

    PackageManagerInternal getPackageManagerInternalLocked() {
        if (mPmInternal == null) {
            mPmInternal = LocalServices.getService(PackageManagerInternal.class);
        }
        return mPmInternal;
    }
    

    可以看到,这里是通过LocalServices保存和获取对应的Internal的,前面的ActivityTaskManagerService也是通过它保存的ActivityTaskManagerInternal,那么这里的PackageManagerInternal实际上是什么呢?看名字我们分析这应该是和包管理相关的,顺着这个思路我们在PackageManagerService中找到了:

    LocalServices.addService(
            PackageManagerInternal.class, new PackageManagerInternalImpl());
    

    再往下就走到Package解析里去了,只需要知道这里的processName是根据包名生成的。

    startSpecificActivityLocked分了两个逻辑,一个是需要创建新进程的,一个是不需要的。

  • 依附于当前进程的Activity启动:realStartActivityLocked

    如果Activity所附属的进程已启动,则会直接进入realStartActivityLocked逻辑分支。

    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
    
        ...
        r.setProcess(proc);
        ...
        ...
        // Create activity launch transaction.
        final ClientTransaction clientTransaction = ClientTransaction.obtain(
                proc.getThread(), r.appToken);
        final DisplayContent dc = r.getDisplay().mDisplayContent;
        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),...));
    
        // Set desired final state.
        final ActivityLifecycleItem lifecycleItem;
        if (andResume) {
            lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
        } else {
            lifecycleItem = PauseActivityItem.obtain();
        }
        clientTransaction.setLifecycleStateRequest(lifecycleItem);
    
        // Schedule transaction.
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    
        ...
        // Perform OOM scoring after the activity state is set, so the process can be updated with the latest state.
        proc.onStartActivity(mService.mTopProcessState, r.info);
        ...
        return true;
    }
    

    scheduleTransaction来自于ClientLifecycleManager:

    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            transaction.recycle();
        }
    }
    

    这里调用了ClientTransaction的schedule方法:

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

    mClient是一个IApplicationThread对象,通过ClientTransaction.obtain方法构造时传入:

    public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
        ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
        if (instance == null) {
            instance = new ClientTransaction();
        }
        instance.mClient = client;
        instance.mActivityToken = activityToken;
    
        return instance;
    }
    

    可见,这个IApplicationThread是proc.getThread(),proc来自于startSpecificActivityLocked方法中的wpc,它通过mService.getProcessController(r.processName, r.info.applicationInfo.uid)获取的,在进程创建的时候ActivityTaskManagerService会保存一个属于这个进程的WindowProcessController,它的Thread就是ApplicationThread(IApplicationThread实现类),ApplicationThread是ActivityThread的内部私有类,因此我们推测它的实例化都是在ActivityThread中完成的(也只能是这样),mService.getProcessController获取的ApplicationThread是怎么来的我们后面再看,现在先看一下它的scheduleTransaction方法:

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

    可见,就是调用的ActvityThread的scheduleTransaction方法,ActvityThread继承自ClientTransactionHandler,scheduleTransaction方法是在ClientTransactionHandler中定义并实现的:

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    

    preExecute我们不用管,只是一些预处理操作回调,我们看见这里调用了sendMessage方法,它在ActivityThread中实现,最终是调用了mH.sendMessage方法,我们看一下mH的msg处理逻辑:

    class H extends Handler {
          ...
        public void handleMessage(Message msg) {
              ...
              case EXECUTE_TRANSACTION:
                 final ClientTransaction transaction = (ClientTransaction) msg.obj;
                 mTransactionExecutor.execute(transaction);
                 ...
                 break; 
              ...
        }
    }
    

    这里调用了TransactionExecutor的execute方法来处理ClientTransaction:

    public void execute(ClientTransaction transaction) {
        ...
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
        ...
    }
    

    这里的核心就是调用了两个方法,先看executeCallbacks:

    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        ...
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            ...
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ...
        }
    }
    

    这里会通过ClientTransaction的getCallbacks方法获取mActivityCallbacks,它是一个ClientTransactionItem集合,然后调用每一个ClientTransactionItem的execute方法,ClientTransactionItem是什么呢?还记得我们前面在realStartActivityLocked方法中调用ClientTransaction的addCallback方法添加的LaunchActivityItem.obtain()实例吗:

    public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info,
            Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo,
            String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
            PersistableBundle persistentState, List<ResultInfo> pendingResults,
            List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo,
            IBinder assistToken) {
        LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
        if (instance == null) {
            instance = new LaunchActivityItem();
        }
        setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
                voiceInteractor, procState, state, persistentState, pendingResults,
                pendingNewIntents, isForward, profilerInfo, assistToken);
    
        return instance;
    }
    

    所以只针对启动而言,会有一个LaunchActivityItem实例存在于mActivityCallbacks中,因此这里也会调用它的execute方法:

    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, mIsForward,
                mProfilerInfo, client, mAssistToken);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
    

    client是前面的mTransactionHandler,在构造TransactionExecutor时传入:

    public final class ActivityThread extends ClientTransactionHandler {
          ...
          private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
          ...
    }
    

    因此client就是ActivityThread,它的handleLaunchActivity方法如下:

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

    内部调用了performLaunchActivity方法创建Activity实例:

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        ...
        ComponentName component = r.intent.getComponent();
        ...
        //创建Activity的Context
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
                  //创建Activity
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ...
        } ...
        try {
              //创建Application
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ...
            if (activity != null) {
                ...
                Window window = null;
                ...
                appContext.setOuterContext(activity);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback,
                        r.assistToken);
                ...
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }
                  ...
                //这里根据是否持久化调用onCreate的不同重载方法
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ...
            }
            ...
        } ...
        ...
        return activity;
    }
    

    可以看到,原来是在这里创建了Context、Activity和Application,而且调用了我们熟悉的onCreate方法。

    你可能会问,怎么没有调用onResume方法呢?还记得前面的TransactionExecutor的execute方法中调用executeCallbacks之后紧跟着还调用了executeLifecycleState方法吗。在executeLifecycleState方法中:

    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        ...
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }
    

    getLifecycleStateRequest获取的就是前面realStartActivityLocked方法中设置的:

    final ActivityLifecycleItem lifecycleItem;
    if (andResume) {
        lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
    clientTransaction.setLifecycleStateRequest(lifecycleItem);
    

    在启动流程场景中andResume传入的是true,这里会根据是否需要显示设置不同的ActivityLifecycleItem,不管是ResumeActivityItem还是PauseActivityItem,其内部的execute逻辑和LaunchActivityItem都是一样的,最终都会通过mH调用到ActivityThread的相关方法里,在那些方法里会调用对应的Activity的生命周期方法,比如onResume或onPause,这个就不再看了。

    到此为止,我们看到了进程已存在的时候Activity是如何启动的,前面我们使用的WindowProcessController的ApplicationThread是进程创建时已经创建好的,那么这个ApplicationThread是怎样创建的呢?

  • 进程不存在时的Activity启动

    通过前面的分析,我们知道在ActivityStackSupervisor的startSpecificActivityLocked方法中,如果Activity需要依附的进程还未启动时会走另一个逻辑分支:

    final Message msg = PooledLambda.obtainMessage(
            ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
            r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
    mService.mH.sendMessage(msg);
    

    这里看到,mService,也就是ActivityTaskManagerService中也有一个mH,这里会给他发送一个消息,经过代码发现PooledLambda.obtainMessage获取的是一个空的Message,并没有设置what属性,而mH的handleMessage方法中并没有处理这种Message的逻辑:

    //ActivityTaskManagerService.H
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case REPORT_TIME_TRACKER_MSG: {
                AppTimeTracker tracker = (AppTimeTracker) msg.obj;
                tracker.deliverResult(mContext);
            } break;
        }
    }
    

    那么它是怎么继续工作的呢?

    我们发现,这里使用Lambda语法传递了一个ActivityManagerInternal::startProcess函数,obtainMessage方法的其他参数是要传给startProcess的参数:

    static <A, B, C, D, E, F> Message obtainMessage(
            HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function,
            A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
        synchronized (Message.sPoolSync) {
            PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                    function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
                    null);
            return Message.obtain().setCallback(callback.recycleOnUse());
        }
    }
    

    acquire会创建或者复用一个PooledLambdaImpl对象,它持有一个mFunc字段,指向的是一个由编译器根据Lambda规则生成的Consumer实现类对象,内部持有了ActivityManagerInternal::startProcess函数,mArgs数组持有该函数需要的参数。

    mH调用sendMessage的时候内部会设置该msg的target为mH本身,然后根据Looper原理,sendMessage方法会走到msg.target的dispatchMessage方法(在Handler中定义并实现的):

    public void dispatchMessage(@NonNull Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }
    

    可以看到,因为我们前面给Message设置了callback,所以这里不会走Handler的handleMessage方法,而是走了handleCallback方法:

    private static void handleCallback(Message message) {
        message.callback.run();
    }
    

    可见在这里调用了callback的run方法,根据前面的分析,callback就是PooledLambdaImpl,它的run方法在其父类OmniFunction中实现:

    @Override
    public void run() {
        invoke(null, null, null, null, null, null, null, null, null);
    }
    

    invoke方法是在PooledLambdaImpl中实现:

    @Override
    R invoke(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
            Object a8, Object a9) {
        ...
        try {
            return doInvoke();
        } finally {
            if (isRecycleOnUse()) doRecycle();
            if (!isRecycled()) {
                int argsSize = ArrayUtils.size(mArgs);
                for (int i = 0; i < argsSize; i++) {
                    popArg(i);
                }
            }
        }
    }
    

    这里又会调用doInvoke方法:

    private R doInvoke() {
        final int funcType = getFlags(MASK_FUNC_TYPE);
        final int argCount = LambdaType.decodeArgCount(funcType);
        final int returnType = LambdaType.decodeReturnType(funcType);
        switch (argCount) {
            ...
            case 6: {
                switch (returnType) {
                    case LambdaType.ReturnType.VOID: {
                        ((HexConsumer) mFunc).accept(popArg(0), popArg(1),
                                popArg(2), popArg(3), popArg(4), popArg(5));
                        return null;
                    }
                    case LambdaType.ReturnType.BOOLEAN: {
                        return (R) (Object) ((HexPredicate) mFunc).test(popArg(0),
                                popArg(1), popArg(2), popArg(3), popArg(4), popArg(5));
                    }
                    case LambdaType.ReturnType.OBJECT: {
                        return (R) ((HexFunction) mFunc).apply(popArg(0), popArg(1),
                                popArg(2), popArg(3), popArg(4), popArg(5));
                    }
                }
            } break;
                  ...
        }
          ...
    }
    

    这里会根据参数的个数选择对应的执行分支,我们这里用的是6个参数函数,因此这里会走到6这个分支,再根据返回类型决定执行mFunc的哪个方法,这里因为传入的是VOID类型,所以会执行accept方法,jdk1.8编译器会根据Lambda规则生成Consumer实现代码,在accept中调用真正的函数,也就是ActivityManagerInternal::startProcess函数。

    那么调用哪个实例的startProcess函数呢?前面的obtainMessage方法中第二个参数传入的mService.mAmInternal是一个ActivityManagerInternal实例:

    mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
    

    我们找到LocalServices添加它的地方在ActivityManagerService的start方法中:

    LocalServices.addService(ActivityManagerInternal.class, new LocalService());
    

    所以真正调用的是LocalService的startProcess函数:

    @Override
    public void startProcess(String processName, ApplicationInfo info,
            boolean knownToBeDead, String hostingType, ComponentName hostingName) {
        ...
        synchronized (ActivityManagerService.this) {
            startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                    new HostingRecord(hostingType, hostingName),
                    false /* allowWhileBooting */, false /* isolated */,
                    true /* keepIfLarge */);
        }
        ...
    }
    

    之后经过以下的几次调用:

    //ActivityManagerService:
    final ProcessRecord startProcessLocked(String processName,ApplicationInfo info, ...) {
        return mProcessList.startProcessLocked(processName, info, ...);
    }
    
    //ProcessList:
    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,...){
        ...
        final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
          ...
        return success ? app : null;
    }
    
    final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
                String abiOverride) {
        return startProcessLocked(app, hostingRecord,...);
    }
    
    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,...) {
        ...
        //调用重载方法
        return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                 runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,                                            invokeWith,startTime);
    }
    
    boolean startProcessLocked(HostingRecord hostingRecord,
                String entryPoint,
                ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
                String seInfo, String requiredAbi, String instructionSet, String invokeWith,
                long startTime) {
         ...
         final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                entryPoint, app,uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi,                          instructionSet,invokeWith, startTime);
           handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,startSeq,                         false);
           ...
    }
    

    最终来到了startProcess方法:

    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        try {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkSlow(startTime, "startProcess: asking zygote to start proc");
            final Process.ProcessStartResult startResult;
            if (hostingRecord.usesWebviewZygote()) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else if (hostingRecord.usesAppZygote()) {
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
    
                startResult = appZygote.getProcess().start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        /*useUsapPool=*/ false,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else {
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            }
            checkSlow(startTime, "startProcess: returned from zygote!");
            return startResult;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }
    

    这里有三种启动方式,通过Process来创建进程:

    public boolean usesAppZygote() {
        return mHostingZygote == APP_ZYGOTE;
    }
    public boolean usesWebviewZygote() {
        return mHostingZygote == WEBVIEW_ZYGOTE;
    }
    

    因为mHostingZygote属性只能通过构造HostingRecord时传入,ActivityManagerservice的startProcess方法中传入的HostingRecord是两个参数的构造方法创建的:

    public HostingRecord(String hostingType, ComponentName hostingName) {
        this(hostingType, hostingName, REGULAR_ZYGOTE);
    }
    

    此处传入的默认mHostingZygote是REGULAR_ZYGOTE,因此这里会走到Process.start启动逻辑:

    public static ProcessStartResult start(@NonNull final String processClass,...) {
        return ZYGOTE_PROCESS.start(processClass, ...);
    }
    

    再往下就是Process的启动逻辑了,又是另一个章节了,不是我们目前的目标。

    到现在为止,我们看到了新进程创建完成了,但是没看见Activity启动。回到最后一级startProcessLocked方法,startProcess方法之后调用了handleProcessStartedLocked方法:

    boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
            long expectedStartSeq, boolean procAttached) {
        ...
        mService.mPidsSelfLocked.put(app);
        ...
        return true;
    }
    

    这里就是进程创建完需要逻辑回调的地方。mService是ActivityManagerService,mPidsSelfLocked是一个PidMap,它的put方法如下:

    void put(ProcessRecord app) {
        synchronized (this) {
            mPidMap.put(app.pid, app);
        }
        mAtmInternal.onProcessMapped(app.pid, app.getWindowProcessController());
    }
    

    ActivityManagerService的mAtmInternal是通过key为ActivityTaskManagerInternal添加到LocalServices中的,它实际上是:

    //ActivityManagerService的start方法中:
    LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
    //ActivityManagerService构造方法中:
    mInternal = new LocalService();
    

    所以看LocalService的onProcessMapped方法:

    @Override
    public void onProcessMapped(int pid, WindowProcessController proc) {
        synchronized (mGlobalLock) {
            mProcessMap.put(pid, proc);
        }
    }
    

    还记得之前在startSpecificActivityLocked方法中分成两个逻辑时是根据什么判断的吗?正是ActivityTaskManagerService的getProcessController方法:

    WindowProcessController getProcessController(int pid, int uid) {
        final WindowProcessController proc = mProcessMap.getProcess(pid);
        if (proc == null) return null;
        if (UserHandle.isApp(uid) && proc.mUid == uid) {
            return proc;
        }
        return null;
    }
    

    因此进程创建完就会把新进程的WindowProcessController添加到mProcessMap中。但是现在添加太晚了啊,startSpecificActivityLocked的判断逻辑已经过去了呀,整个逻辑又怎么再次回到startSpecificActivityLocked中的呢?即现在无法再回到过去转而调用realStartActivityLocked了啊。

    这里就需要熟悉Zygote的知识了,Zygote进行fork出子进程后会调用到ActivityThread的main方法,Zygote分析得另开一文,这里只需要先这么记住。

    main方法里有这么两句:

    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    

    ActivityThread的attach方法中有:

    final IActivityManager mgr = ActivityManager.getService();
    mgr.attachApplication(mAppThread, startSeq);
    

    我们已经知道IActivityManager的实现类就是ActivityManagerService,它的attachApplication方法调用了attachApplicationLocked方法,这个方法内会调用mAtmInternal.attachApplication(app.getWindowProcessController())方法,前面我们知道mAtmInternal就是ActivityTaskManagerService.LocalService,它的attachApplication方法如下:

    public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
        synchronized (mGlobalLockWithoutBoost) {
            return mRootActivityContainer.attachApplication(wpc);
        }
    }
    

    这里又会调用到RootActivityContainer的attachApplication方法:

    boolean attachApplication(WindowProcessController app) throws RemoteException {
        final String processName = app.mName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ActivityDisplay display = mActivityDisplays.get(displayNdx);
            final ActivityStack stack = display.getFocusedStack();
            if (stack != null) {
                  //获取目标栈中所有的需要显示的ActivityRecord
                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
                final ActivityRecord top = stack.topRunningActivityLocked();
                final int size = mTmpActivityList.size();
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
                    if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                            if (mStackSupervisor.realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                    + top.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
        }
        return didSomething;
    }
    

    可以看到,这里会取到焦点Stack,然后遍历其所有的Activity,调用ActivityStackSupervisor的realStartActivityLocked方法把它们创建或者恢复到正常生命周期。

    所以如果创建Activity之前需要启动新进程的情况的话,在进程启动完之后会直接调用realStartActivityLocked方法创建Activity,不再通过startSpecificActivityLocked方法的分支走了。

  • 总结

    我们根据API29的源码分析了整个Activity的启动过程,其中又分成新进程启动方式和当前进程内启动方式两种。分析过后,我认为在API29的源码逻辑下,整个Activity的启动逻辑分成4部分:

    • 角色进场

      1. 首先,Instrumentation负责以Binder的方式引出ActivityTaskManagerService,调用它的startActivity方法开启创建。

      2. 启动之后,它会根据启动结果值判断是否启动成功,如果失败会由它来负责爆出对应错误。

    • Stack信息的创建和维护

      1. 进入到ActivityTaskManagerService的startActivity逻辑后,它会通过内部的ActivityStartController创建或获取一个ActivityStarter,然后通过它的一系列链式方法把启动信息封装到一个ActivityStarter.Request对象中,然后调用ActivityStarter的execute方法。

      2. execute方法中会调用startActivityMayWait方法,它会通过一系列startActivity重载方法调用到startActivityUnchecked方法中,这个方法中会根据Activity的启动信息(ActivityRecord)找到所在的目标栈(mTargetStack),如果没找到则会创建一个,然后把这个栈对象设置成焦点栈并移到前台(如果Activity需要被显示的话)。

      3. 然后调用了RootActivityContainer的resumeFocusedStacksTopActivities方法。在这个方法中,会调用目标栈对象(ActivityStack)的resumeTopActivityUncheckedLocked方法,其内部又会调用resumeTopActivityInnerLocked方法,这个方法内部又会调用startSpecificActivityLocked方法,从这里开始分成上述的两种启动方式。

    • Activity创建逻辑

      在不需要创建新进程时,也就是在当前进程下创建Activity时,这部分逻辑的入口在ActivityStackSupervisor的realStartActivityLocked方法。

      1. 这个方法中会获取一个ClientTransaction对象,然后给它添加一个叫LaunchActivityItem的callback,再设置一个叫做ActivityLifecycleItem,如果是需要显示的Activity则设置ResumeActivityItem,否则设置PauseActivityItem。然后获取ActivityTaskManagerService的mLifecycleManager(ClientLifecycleManager),调用它的scheduleTransaction方法,把ClientTransaction对象传进去。
      2. scheduleTransaction方法中会调用ClientTransaction对象的schedule方法。
      3. schedule方法中会调用ApplicationThread的scheduleTransaction方法,ApplicationThread是ActivityThread的内部类,它继承自IApplicationThread.Stub,它的scheduleTransaction方法中调用了ActivityThread.this.scheduleTransaction方法,ActivityThread的scheduleTransaction方法实现在其父类ClientTransactionHandler中,在这里调用sendMessage方法,这个方法在ActivityThread里实现,在这里调用了mH的sendMessage方法,mH是ActivityThread.H。
      4. ActivityThread.H的handleMessage方法里处理EXECUTE_TRANSACTION这个信息,会调用TransactionExecutor的execute方法,传入的是ClientTransaction,这个方法里会调用executeCallbacks和executeLifecycleState方法。
      5. executeCallbacks内部会获取ClientTransaction的所有callback(ClientTransactionItem),然后调用每一个ClientTransactionItem的execute方法,自然也包括前面设置的LaunchActivityItem,它的execute方法中会调用传入的参数—ClientTransactionHandler—的handleLaunchActivity方法,传入的这个ClientTransactionHandler就是构造TransactionExecutor时传入的ActivityThread,因此handleLaunchActivity方法位于ActivityThread中,这个方法中又会调用performLaunchActivity方法,在其中会创建Activity实例、调用activity的attach、onCreate方法。
      6. executeLifecycleState方法逻辑中会找到设置的ActivityLifecycleItem,也就是ResumeActivityItem或PauseActivityItem,和LaunchActivityItem的流程一样,最终会调用activity的onResume或onPause方法。
    • 新进程启动方式中回调到Activity启动逻辑的流程

      1. 在新进程启动方式中需要Zygote的知识才能理解回到启动Activity的逻辑。只需要知道Zygote启动完成后会调用ActivityThread的main函数。
      2. 在main函数中会调用ActivityThread的attach方法,它会调用到ActivityManagerService的attachApplication方法,这个方法又会调用ActivityTaskManagerService.LocalService的attachApplication方法。
      3. 然后又调用RootActivityContainer的attachApplication方法,在这个方法中会把焦点Stack内部的Activity信息依次传入ActivityStackSupervisor的realStartActivityLocked方法,到这就进入了同样的Activity的创建逻辑。

相关文章

网友评论

      本文标题:Activity启动流程分析

      本文链接:https://www.haomeiwen.com/subject/dsfuqdtx.html