Android 11 Activity启动流程分析

Android 11 Activity启动流程分析

本片文章是基于Android 11版本来分析应用Activity的启动的,Activity是Android四大组件中最重要的一个,因为我们所有的页面基本上都是基于Activity开发的,所以了解Activity是怎么启动的是很有必要的,接下来我们就来分析一下Activity的启动流程。

Activty启动调用时序图

Android 11 Activity启动流程分析_第1张图片

下面我们就来根据这张时序图来具体看一下代码中的调用流程
我们一般在开发中会用下面的方法来启动一个Activity,那我们分析源码的如果其实就是这里

startActivity(intent);

点击上面方法会跳转到Activity的startActivity方法中代码如下:

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

这个方法最终会调用到Activity的startActivityForResult()方法中,接下来我们看一下startActivityForResult()方法干了什么事情。


public void startActivityForResult(
            String who, Intent intent, int requestCode, @Nullable Bundle options) {
         ...
         //1
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, who,
                intent, requestCode, options);
        ...
    }

从注释1中可以看出这个方法又调用了Instrumentation的execStartActivity()方法,接下来我们就来看一下execStartActivity方法内部是怎么实现的:

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
            
          //省略ActivityMonitor相关代码
        try {
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            //1
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getBasePackageName(), who.getAttributionTag(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                    target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

关键部分在注释1处,这个调用了ActivityTaskManager的getservice方法,这个方法其实获取的是IActivityTaskManager这个AIDL接口,具体的实现类是ActivityTaskManagerService,接下来我们看一下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) {
                //1
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

从注释1中可以看出这个调用了自己的startActivityAsUser方法,这里有两个重载的方法,我们主要看第二个startActivityAsUser()。代码如下:

 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.
        //1
        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();

    }

这段代码关键的部分是注释1处,这个里构建了一个ActivityStarter并设置了一些配置,最终执行了ActivityStarter的execute()方法,接下来我们就看一下execute方法的具体实现。代码如下:

int execute() {
        try {
            // Refuse possible leaked file descriptors
            if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
                throw new IllegalArgumentException("File descriptors passed in Intent");
            }

                 ...
                 //1
                res = executeRequest(mRequest);

                ...
                return getExternalResult(mRequest.waitResult == null ? res
                        : waitForResult(res, mLastStartActivityRecord));
            }
        } finally {
            onExecutionComplete();
        }
    }

这个方法比较长,我们只看关键部分其他部分这里就删除掉了,我们主要看一下注释1部分。其实这个的mRequest是在我们上面构建ActivityStarter的时候就会被创建,并且上面的对ActivityStarter的一些参数设置其实是设置给了Request这个内部类。最终回调用ActivityStarter的executeRequest方法。接下我们看一下executeRequest方法内部是怎么实现的。代码如下:

 private int executeRequest(Request request) {
        //注释1
        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);
        mLastStartActivityRecord = r;

        if (r.appTimeTracker == null && sourceRecord != null) {
            // If the caller didn't specify an explicit time tracker, we want to continue
            // tracking under any it has.
            r.appTimeTracker = sourceRecord.appTimeTracker;
        }

        final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();

        // If we are starting an activity that is not from the same uid as the currently resumed
        // one, check whether app switches are allowed.
        if (voiceSession == null && stack != null && (stack.getResumedActivity() == null
                || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                    realCallingPid, realCallingUid, "Activity start")) {
                if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
                    mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
                            sourceRecord, startFlags, stack, callerApp, intentGrants));
                }
                ActivityOptions.abort(checkedOptions);
                return ActivityManager.START_SWITCHES_CANCELED;
            }
        }

        mService.onStartActivitySetDidAppSwitch();
        mController.doPendingActivityLaunches(false);
        //2
        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部分,这里构建了一个ActivityRecord,这个应该是我们比较熟悉的类了其实这个类就是对Activity的一些信息的封装类,代表着返回栈的一条记录。关键部分是注释2处,这里可以看到它调用的自己的startActivityUnchecked方法,接下来我们看一下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) {
             //1
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
        } finally {
        ...
        }
        return result;
    }

这个方法在注释1处调用了自己的startActivityInner()方法,代码如下:

   int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor, restrictedBgActivity);
            ...
                //1
                mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
            ...
        return START_SUCCESS;
    }

这个方法的作用主要是,启动一个活动,并确定该活动是否应该添加到现有活动的顶部,省略了一些关于任务栈的判断逻辑,关键部分是注释1处,可以看出它调用了RootWindowContainer这个类的resumeFocusedStacksTopActivities方法。这个方法的代码如下:

boolean resumeFocusedStacksTopActivities(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
            ...
            if (!resumedOnDisplay) {
                // In cases when there are no valid activities (e.g. device just booted or launcher
                // crashed) it's possible that nothing was resumed on a display. Requesting resume
                // of top activity in focused stack explicitly will make sure that at least home
                // activity is started and resumed, and no recursion occurs.
                final ActivityStack focusedStack = display.getFocusedStack();
                if (focusedStack != null) {
                    //1
                    result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
                } else if (targetStack == null) {
                    result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                            display.getDefaultTaskDisplayArea());
                }
            }
        }

        return result;
    }

这段代码终于看到了我们熟悉的类ActivityStack,关键代码是注释1部分,这里调用了ActivityStack的
resumeTopActivityUncheckedLocked()方法,这个方法的代码如下:

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

这个方法的关键部分是注释1,这里它又调用了自己的resumeTopActivityInnerLocked()方法,这个方法的代码如下:

  private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
            // Not ready yet!
            return false;
        }
        ...
        ActivityRecord next = topRunningActivity(true /* focusableOnly */);
        ...
           //1
            mStackSupervisor.startSpecificActivity(next, true, true);
        }

        return true;
    }

这个代码也很长,主要住一些ActivityRecord类状态的判断和更新,关键部分是最后注释1的部分,这里会调用ActivityStackSupervisor的startSpecificActivity()方法,这个方法代码如下:

 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;
        if (wpc != null && wpc.hasThread()) {
            try {
                //1
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }
            ...
        }
    }

这里关键部分是注释1处,这里调用了自己的realStartActivityLocked()方法,这里从名字可以看出是真正的启动Activity了,这个方法的代码如下:

  boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {

                   ...
                  //1 
                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);

                final DisplayContent dc = r.getDisplay().mDisplayContent;
               //2
                 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.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                        r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));

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

                // Schedule transaction.
                //3
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);

              ...

        return true;
    }

这一段代码注释1处创建ClientTransaction对象,然后在注释2处通过clientTransaction.addCallback添加一个LaunchActivityItem对象,(LaunchActivityItem.obtain方法返回的是一个LaunchActivityItem对象)此处尤为重要,因为下面的流程会回调到这LaunchActivityItem这个类中。
然后调用ClientLifecycleManager的scheduleTransaction方法把当前的是事务进行提交。接下来看一下ClientLifecycleManager的scheduleTransaction的具体实现,代码如下:

    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
       ...
    }

这里调用了ClientTransaction的schedule()方法,schedule方法的代码如下:

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

这里调用了mClient的scheduleTransaction()方法,那mClient是谁呢?其实mClient其实就是
IApplicationThread这个AIDL接口,具体的实现类其实是ActivityThread的内部类ApplicationThread,
从这个类继承自IApplicationThread.Stub我们就可以看出IApplicationThread是一个AIDL接口。那接下来我们看一下ApplicationThread的scheduleTransaction方法。代码如下:

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

这个方法调用了ActivityThread的scheduleTransaction()方法,但是我们在ActivityThread并没有找到这个方法,其实这个方法在ActivityThread的父类ClientTransactionHandler 事务处理器中。接下类我们看一下ClientTransactionHandler中的scheduleTransaction方法。代码如下:

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

这里我们可以看到它是通过调用ActivityThread的sendMessage方法,给handler的子类H发了一个what为 EXECUTE_TRANSACTION obj为ClientTransaction的消息接下来我们在H类的handleMessage方法中可以看到调用了TransactionExecutor事务执行器的execute()方法并把ClientTransaction 作为参数,execute方法代码如下:

    public void execute(ClientTransaction transaction) {
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
        ...
        //1
        executeCallbacks(transaction);
        //2
        executeLifecycleState(transaction);
        ...
    }

这个方法主要关键部分是注释1和注释2,注释2是Activity声明周期的,我们主要还是来看注释1处,这里调用自己的executeCallbacks方法,具体代码如下:

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

从注释1可以看到这里调用ClientTransactionItem的execute方法,这就是我为什么在上面分析realStartActivityLocked方法是说,ClientTransactionItem这个类很重要,就体现在这里。我们发现这个类是一个抽象类,具体的实现类其实就是我们上面realStartActivityLocked中注释2中构建的LaunchActivityItem,所以我们看一下LaunchActivityItem的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, mFixedRotationAdjustments);
           //1
         client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

在这里我们终于看到我们熟悉的东西了handleLaunchActivity方法(注释1),那这个client是谁呢?通过上面的分析我们可以知道这个client其实就是ActivityThread这个类,ActivityThread继承自ClientTransactionHandler。接下来我们看一下ActivityThread的handleLaunchActivity方法的具体实现。代码如下:

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

          ....

        return a;
    }

这个方法内部调用了自己的performLaunchActivity()方法。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...

        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //1
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            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 {
            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());

                ...
                // 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);
                //2
                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);
                ...
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    //3
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
             ...

        return activity;
    }

在注释1处我们可以发现它会创建Activity实例,然后调用还创建了appContext的然后在注释2处调用Activity的attach方法来绑定appContent,接下来在注3处调用了Instrumentation这个类的callActivityOnCreate()方法。

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

这里调用了Activity的performCreate方法,具体实现代码如下:

    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ...
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
         ...
    }

到这里就会回调到我们创建Activity复写的onCreate方法了。到这里整个Activity的启动流程也就分析完了。从文章最上面的调用时序图可以看出Activity的启动流程还是比较复杂的,涉及的类也比较多,每个方法的逻辑也是非常复杂我们千万不要抠细节要不然就会迷失在代码的海洋中无法自拔。

你可能感兴趣的:(android,源码分析,基础,java,android)