Activity启动流程源码解析

Activity的启动流程一般可以分为两种,一种是应用程序根Activity的启动,而另一种则是普通Activity的启动。根Activity的启动是指应用程序启动后展示的第一个Activity(即intent-filter里面对应的action为MAIN,category为LAUNCHER的Activity),因此启动这种Activity可以理解为启动应用程序,其启动过程也就是应用程序的启动过程。普通Activity的启动是指应用程序进程已经启动,启动一个除根Activity之外的其它Activity。

本文主要介绍普通Activity启动过程的源码分析,而且源码版本基于Android 8.0。至于根Activity的启动过程(即应用程序的启动过程),其启动过程与普通Activity启动过程是有重叠的,有兴趣的可以自己去阅读源码了解一下,从LauncherActivity的onListItemClick()方法开始。

普通Activity的启动流程可以分为一下3个步骤:

  • 启动Activity请求AMS过程
  • AMS到ApplicationThread调用过程
  • ActivityThread启动Activity过程

一、启动Activity请求AMS过程

启动Activity时会调用startActivity方法,那我们就从Activity的startActivity(Intent intent)方法开始吧:

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

我们看到这个startActivity(Intent intent)方法又会去调用重载的startActivity(Intent intent, @Nullable Bundle options)方法:

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

由于这里我们传入的options为null,所以转而调用startActivityForResult(intent, -1)方法,之后最终又会调用到startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options)方法:

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
        }
        ... ...
    }

这里我们只重点关注Activity启动相关部分,由于我们是第一次启动Activity,所以这里的mParent为空,执行该if分支,然后调用Instrumentation的execStartActivity()方法:

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ... ...
        try {
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

我们这里先简单了解一下Instrumentation,Instrumentation主要用来监控应用程序和系统的交互,Activity在应用进程端的启动实际上就是通过Instrumentation来执行具体的操作。同样,我们只关注重点部分,发现在这个方法中主要调用ActivityManager.getService()的startActivity方法。那么,我们就需要通过源码具体看下ActivityManager.getService()返回的到底是哈,具体源码在ActivityManager类中,如下:

    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton IActivityManagerSingleton =
            new Singleton() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

看到这里,了解过Android中Binder机制的同学一下子应该就明白了,调用ActivityManager的getService()方法获取到的是AMS(ActivityManagerService)在本地的代理对象。顺便说一下,这个源码是基于Android 8.0的,采用的是AIDL的实现方式,这与之前的实现方式略微有些差别,Android 8.0之前是通过ActivityManagerNative.getDefault()来获取AMS的代理对象的。

那么,我们回到Instrumentation的execStartActivity()方法,现在应该就很明确了,该方法最终的目的是要调用AMS的startActivity()方法。接下来,我们的任务就是分析在AMS中的具体调用过程。

二、AMS到ApplicationThread调用过程

由上面的分析可知,应用程序开启一个普通Activity,在经过Instrumentation的execStartActivity()方法调用后,通过Binder机制,会跨进程调用到SystemServer进程AMS的startActivity()方法,看一下具体的源码:

    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

该方法又会继续调用startActivityAsUser()方法:

    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null,
                "startActivityAsUser");
    }

紧接着,又会调用到ActivityStarter类的startActivityMayWait()方法,该方法实现代码较长,同样我们只挑重点看就可以了:

    final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask, String reason) {
        ... ...
        int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor,
                resultTo, resultWho, requestCode, callingPid,
                callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                inTask, reason);
        ... ...
    }

由上面的源码可知,startActivityMayWait()方法又会转而去调用startActivityLocked()方法:

    int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask, String reason) {
        ... ...
        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                container, inTask);
        ... ...
    }

由上面的源码可知,startActivityLocked()方法又会转而去调用ActivityStarter类的startActivity()方法,同样我们只关注重点部分:

    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
        ... ...
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }

好吧,我们看到它又去调用了startActivity()的另一个重载方法:

    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        int result = START_CANCELED;
        try {
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        } finally {
            // If we are not able to proceed, disassociate the activity from the task. Leaving an
            // activity in an incomplete state can lead to issues, such as performing operations
            // without a window container.
            if (!ActivityManager.isStartResultSuccessful(result)
                    && mStartActivity.getTask() != null) {
                mStartActivity.getTask().removeActivity(mStartActivity);
            }
            mService.mWindowManager.continueSurfaceLayout();
        }

        postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId,  mSourceRecord,
                mTargetStack);

        return result;
    }

由上面的源码可知,该方法又去调用了startActivityUnchecked()方法,同样只关注重点部分:

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        ... ...
        mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
        ... ...
    }

由上面的源码可知,该方法又去调用了ActivityStackSupervisor类的resumeFocusedStackTopActivityLocked()方法:

    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.state == RESUMED) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }
        return false;
    }

紧接着,又会去调用ActivityStack类的resumeTopActivityUncheckedLocked()方法:

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        // When resuming the top activity, it may be necessary to pause the top activity (for
        // example, returning to the lock screen. We suppress the normal pause logic in
        // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the end.
        // We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here to ensure
        // any necessary pause logic occurs.
        mStackSupervisor.checkReadyForSleepLocked();

        return result;
    }

紧接着,又去调用了resumeTopActivityInnerLocked()方法,该方法代码很长,我们只挑重点看:

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ... ...
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            // 回调栈顶Activity的onPause()方法
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
        ... ...
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
        ... ...
    }

这里,我们稍微提一下,就是在启动一个新的Activity之前,会先回调栈顶Activity的onPause()方法。接着,我们来看下startSpecificActivityLocked()方法的实现:

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.getStack().setLaunchTime(r);

        if (app != null && app.thread != null) {
        // 应用程序进程已经存在
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, 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.
        }

        // 应用程序进程不存在,则启动应用程序进程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

分析一下startSpecificActivityLocked()源码,我们可以知道,如果应用程序的进程已经存在的话,就会去调用realStartActivityLocked()方法,那么这个方法代码也很长,我们依然只关注重点部分:

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ... ...
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    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, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);
        ... ...
    }

由源码可知,这里的app.thread是IApplicationThread,同样是AIDL实现方式,ActivityThread的内部类ApplicationThread继承了IApplicationThread.Stub。那么,这个很明显又是通过Binder机制进行跨进程调用,只不过现在SystemServer进程相当于是client端,App进程相当于是server端。

回到realStartActivityLocked()方法,目标就很明确了,就是要调用ActivityThread的scheduleLaunchActivity()方法。接下来,我们的任务就是分析ActivityThread中启动Activity的过程。

三、ActivityThread启动Activity过程

由上面的分析可知,在AMS中经过realStartActivityLocked()方法的调用后,通过Binder机制,会跨进程调用到App进程中主线程ActivityThread的scheduleLaunchActivity()方法,从方法名上我们也可以猜出来是处理启动Activity的,来看一下具体的源码:

    @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List pendingResults, List pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

可以看到,scheduleLaunchActivity()方法将启动Activity的参数封装成ActivityClientRecord对象,通过sendMessage()方法向H发送LAUNCH_ACTIVITY消息。那这个H明显就是一个Handler,事实上它就是ActivityThread的一个内部类并且继承Handler,是App进程中主线程的消息管理类。了解Binder的同学应该知道,scheduleLaunchActivity()方法的调用肯定是在Binder线程池中的,所以这里需要使用主线程的Handler将代码逻辑切换到主线程。
接下来,我们看下H的handleMessage()方法对LAUNCH_ACTIVITY消息的处理:

    private class H extends Handler {
        ... ...
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } 
                break;
                ... ...
            }
            ... ...
    }

紧接着,会调用handleLaunchActivity()方法:

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ... ...
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
            ... ...
            }
        }
        ... ...
    }

很明显,接着又会去调用performLaunchActivity()方法,同样我们只关注重点部分:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        ... ...
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
        } catch (Exception e) {
            ... ...
            }
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (activity != null) {
                ... ...
                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);
                ... ...
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ... ...
                if (!r.activity.mFinished) {
                    // 回调onStart()方法
                    activity.performStart();
                    r.stopped = false;
                }             
            }
            mActivities.put(r.token, r);
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            ... ...
        }
        return activity;
    }

首先,我们看到Activity的实例是通过Instrumentation的newActivity()方法创建的,而且是通过反射的方式创建的,具体实现如下:

    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }

其次,我们看到通过makeApplication()方法创建了应用程序的application:

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }
        Application app = null;

        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            ... ...
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ... ...
            }
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ... ...
                }
            }
        }
        ... ...
        return app;
    }

最后,我们看到通过调用Instrumentation的callActivityOnCreate()方法,回调启动目标Activity的onCreate()方法:

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

紧接着,会去调用Activity的performCreate()方法:

   final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

看到这里,我们的Activity终于是被启动了,紧接着它的onStart()和onResume()生命周期方法也会依次得到回调,至此Activity就呈现在我们眼前了,那么Activity的启动流程到此为止也就结束了。

总结

普通Activity的启动流程主要涉及了两个进程,分别是AMS所在SystemServer进程和应用程序进程,通过Binder机制进行跨进程通信,相互配合,最终完成Activity的启动。

你可能感兴趣的:(Activity启动流程源码解析)