Android startActivity流程分析 Android 10 [API 29]

语言: CN / TW / HK

startActivity

startActivity常用两种方式:

1.端内Activity.startActivity

2.LauncherAppsService#startActivityAsUser

两种方式最终都是通过ActivityTaskManagerService进行处理。

以端内Intent方式打开startActivity为例,最终调用的方法为startActivityForResult

Activity.java   public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,            @Nullable Bundle options) {       .....            Instrumentation.ActivityResult ar =                mInstrumentation.execStartActivity(                    this, mMainThread.getApplicationThread(), mToken, this,                    intent, requestCode, options);            if (ar != null) {                mMainThread.sendActivityResult(                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),                    ar.getResultData());           }           .....   }

进入Instrumentation.execStartActivity

Instrumentation.java   public ActivityResult execStartActivity(            Context who, IBinder contextThread, IBinder token, Activity target,            Intent intent, int requestCode, Bundle options) {        IApplicationThread whoThread = (IApplicationThread) contextThread;       .....            int result = ActivityTaskManager.getService()               .startActivity(whoThread, who.getBasePackageName(), intent,                        intent.resolveTypeIfNeeded(who.getContentResolver()),                        token, target != null ? target.mEmbeddedID : null,                        requestCode, 0, null, options);            checkStartActivityResult(result, intent);       .....   }

ActivityTaskManager.getService()返回的是IActivityTaskManager,也就是ActivityTaskManagerService的binder。进而通过binder调用ATMS的startActivity,该方法相当于startActivityAsUser的一个重载,在startActivityAsUser中只是验证了一下userId,构造参数传递给ActivityStarter

ActivityTaskManagerService.java ​ 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"); ​        //返回缓存池中的ActivityStarter对象,并执行        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();   }

这里看到ActivityStartController.obtainStarter()方法联想到Message的obtain,显然是从缓存的数据中获取实例

ActivityStartController.java ​ private final Factory mFactory; ​ ActivityStartController(ActivityTaskManagerService service) {        this(service, service.mStackSupervisor,                new DefaultFactory(service, service.mStackSupervisor,                    new ActivityStartInterceptor(service, service.mStackSupervisor)));   } ​ ActivityStarter obtainStarter(Intent intent, String reason) {        return mFactory.obtain().setIntent(intent).setReason(reason);   }

Factory的实现类为DefaultFactory,工厂模式创建,其中使用了SynchronizedPool来保证线程安全。顾名思义SynchronizedPool的acquire和release逻辑是在synchronized代码块中的。

static class DefaultFactory implements Factory {       ....        private final int MAX_STARTER_COUNT = 3;       .....        private SynchronizedPool<ActivityStarter> mStarterPool =                new SynchronizedPool<>(MAX_STARTER_COUNT);       ......        @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);       }   }

ActivityStarter

ActivityStarter中做了如下操作:

通过PMS解析Intent

权限验证及处理

找到Activity所属的ActivityStack

ActivityStarter.java   int execute() {       ......                return startActivityMayWait(mRequest.caller, mRequest.callingUid,.....);       .....       } finally {            onExecutionComplete();       }   } private int startActivityMayWait(....){ .....  // 通过PMS解析Intent  ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,                                                0 /* matchFlags */,                                                computeResolveFilterUid(                                                  callingUid, realCallingUid, mRequest.filterCallingUid)); .....  synchronized (mService.mGlobalLock) {   .....    final ActivityRecord[] outRecord = new ActivityRecord[1];    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);   .....    return res; } } ​ 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,            SafeActivityOptions options,            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,            PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {        mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent); //权限验证及处理 ....        final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,                true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);        return res;   }   ​ 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;       ......        try {            mService.mWindowManager.deferSurfaceLayout();            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,                    startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);       ......        return result;   }    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,            ActivityRecord[] outActivity, boolean restrictedBgActivity) {   ....      // mTargetStack为ActivityStack即新Activity将要加入的stack      mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,                mOptions);   .... }

ActivityStack中通过resumeTopActivityInnerLocked、resumeTopActivityInnerLocked方法调用最终会走到ActivityStackSupervisor

ActivityStackSupervisor.realStartActivityLocked ()

在该方法中,构造ClientTransaction,并通过addCallback传入LaunchActivityItem,通过setLifecycleStateRequest方式传入ResumeActivityItem。ClientTransaction的执行流程是先处理Callbacks再处理LifecycleState。

``` boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,            boolean andResume, boolean checkConfig) throws RemoteException { ​       ......                // 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),                        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.icicle, r.persistentState, results, newIntents,                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),                                r.assistToken)); ​                // Set desired final state.                final ActivityLifecycleItem lifecycleItem; //startActivity时andResume为true                if (andResume) {                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());               } else {                    lifecycleItem = PauseActivityItem.obtain();               }

            //在callback处理完后,会处理lifecycleItem

clientTransaction.setLifecycleStateRequest(lifecycleItem); ​                // scheduleTransaction方法中,调用clientTransaction.schedule(),通过IApplicationThread进行binder调用将clientTransaction传递给client的ActivityThread进行处理                mService.getLifecycleManager().scheduleTransaction(clientTransaction);       .... ​        return true;   } ``` ClientTransaction图示 ClientTransaction.png

ActivityThread

接上面从ActivityTaskManagerService来到ActivityThread的scheduleTransaction,ActivityThread继承自ClientTransactionHandler,scheduleTransaction定义在其中

mTransactionExecutor.execute会最终调用到callback也就是LaunchActivityItem的execute方法,其中调用了ClientTransactionHandler#handleLaunchActivity,即ActivityThread的handleLaunchActivity

​ void scheduleTransaction(ClientTransaction transaction) {        transaction.preExecute(this);  // 给H发送what为EXECUTE_TRANSACTION的消息,消息体为transaction        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);   } ​ //H中定义的处理逻辑 case EXECUTE_TRANSACTION:        final ClientTransaction transaction = (ClientTransaction) msg.obj;        mTransactionExecutor.execute(transaction);       .....        break; ​ ​ public Activity handleLaunchActivity(ActivityClientRecord r,            PendingTransactionActions pendingActions, Intent customIntent) {       .....        // 建立与WMS的连接        WindowManagerGlobal.initialize(); ​        // Hint the GraphicsEnvironment that an activity is launching on the process.        GraphicsEnvironment.hintActivityLaunch(); ​        final Activity a = performLaunchActivity(r, customIntent); ​        if (a != null) {            r.createdConfig = new Configuration(mConfiguration);            reportSizeConfigurations(r);            if (!r.activity.mFinished && pendingActions != null) {                pendingActions.setOldState(r.state);                pendingActions.setRestoreInstanceState(true);                pendingActions.setCallOnPostCreate(true);           }       } else {            // If there was an error, for any reason, tell the activity manager to stop us.            try {                ActivityTaskManager.getService()                       .finishActivity(r.token, Activity.RESULT_CANCELED, null,                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);           } catch (RemoteException ex) {                throw ex.rethrowFromSystemServer();           }       } ​        return a;   } ​ private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {        ActivityInfo aInfo = r.activityInfo;       ....          //创建Context        ContextImpl appContext = createBaseContextForActivity(r);        Activity activity = null;        try {            java.lang.ClassLoader cl = appContext.getClassLoader();            activity = mInstrumentation.newActivity(                    cl, component.getClassName(), r.intent);       ......        try {            Application app = r.packageInfo.makeApplication(false, mInstrumentation);           ....            if (activity != null) {                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());                Configuration config = new Configuration(mCompatConfiguration);                if (r.overrideConfig != null) {                    config.updateFrom(r.overrideConfig);               }               ....                Window window = null;                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {                    window = r.mPendingRemoveWindow;                    r.mPendingRemoveWindow = null;                    r.mPendingRemoveWindowManager = null;               }                appContext.setOuterContext(activity);              //初始化Activity的baseContext、PhoneWindow                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);               } ​                activity.mCalled = false;                if (r.isPersistable()) {                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);               } else {                    mInstrumentation.callActivityOnCreate(activity, r.state);               }               .....                r.activity = activity;           }            r.setState(ON_CREATE); ​            // updatePendingActivityConfiguration() reads from mActivities to update            // ActivityClientRecord which runs in a different thread. Protect modifications to            // mActivities to avoid race.            synchronized (mResourcesManager) {                mActivities.put(r.token, r);           }         ...... ​        return activity;   }

performLaunchActivity中主要做了以下几件事

创建appContext

通过ContextImpl.createActivityContext(),其中new ContextImpl对象并初始化属性。

private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,            @NonNull LoadedApk packageInfo, @Nullable String splitName,            @Nullable IBinder activityToken, @Nullable UserHandle user, int flags,            @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) {       .....        mMainThread = mainThread;        mActivityToken = activityToken;        mFlags = flags; ​        if (user == null) {            user = Process.myUserHandle();       }        mUser = user; ​        mPackageInfo = packageInfo;        mSplitName = splitName;        mClassLoader = classLoader;        mResourcesManager = ResourcesManager.getInstance();       ......        mContentResolver = new ApplicationContentResolver(this, mainThread);   }

newActivity

通过Instrumentation.newActivity()方法新建Activity对象,其中只是用ClassLoader及ClassName新建了一个对象。

创建Application

通过LoadedApk类进行构造,其中依然使用Instrumentation.newApplication新建Application对象,并attach。

LoadedApk.makeApplication

其中创建了Application,建立了Application与LoadedApk的关联,并回调了Application的onCreate()

LoadedApk.java ​ public Application makeApplication(boolean forceDefaultAppClass,            Instrumentation instrumentation) {        //若mApplication已经创建则直接返回mApplication        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();            if (!mPackageName.equals("android")) {                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,                        "initializeJavaContextClassLoader");                initializeJavaContextClassLoader();                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);           }            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);            app = mActivityThread.mInstrumentation.newApplication(                    cl, appClass, appContext);            appContext.setOuterContext(app);       .....        mActivityThread.mAllApplications.add(app);          //这里为mApplication赋值,后续Context.getApplicationContext得到的就是此对象        mApplication = app; ​        if (instrumentation != null) {            try {                instrumentation.callApplicationOnCreate(app);           ......       } .....        return app;   }

通过Instrumentation新建

Instrumentation.java public Application newApplication(ClassLoader cl, String className, Context context)            throws InstantiationException, IllegalAccessException,            ClassNotFoundException {        Application app = getFactory(context.getPackageName())               .instantiateApplication(cl, className);        //执行了attach        app.attach(context);        return app;   }

Application.attach方法将传入的context设为baseContext,并与PackageInfo关联

/* package */ final void attach(Context context) {        attachBaseContext(context);        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;   }

这里传入的context是上一步通过ContextImpl.createAppContext(mActivityThread, this);创建的。最终ContextImpl的构造函数中activityInfo,activityToken都为为null

ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,                null, opPackageName); ​ //与createActivityContext的参数对比 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,                activityToken, null, 0, classLoader, null);

Activity初始化回调

performLaunchActivity后面部分包含了初始化Configuration、activity.attach、setTheme

activity.attach方法中,对Activity的成员变量初始化

Activity.java ​ final void attach(Context context, ActivityThread aThread,            Instrumentation instr, IBinder token, int ident,            Application application, Intent intent, ActivityInfo info,            CharSequence title, Activity parent, String id,            NonConfigurationInstances lastNonConfigurationInstances,            Configuration config, String referrer, IVoiceInteractor voiceInteractor,            Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {  //初始化Activity的baseContext        attachBaseContext(context); ​        mFragments.attachHost(null /*parent*/); ​        mWindow = new PhoneWindow(this, window, activityConfigCallback);        mWindow.setWindowControllerCallback(this);        mWindow.setCallback(this);        mWindow.setOnWindowDismissedCallback(this);        mWindow.getLayoutInflater().setPrivateFactory(this);        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {            mWindow.setSoftInputMode(info.softInputMode);       }        if (info.uiOptions != 0) {            mWindow.setUiOptions(info.uiOptions);       }        mUiThread = Thread.currentThread(); ​        mMainThread = aThread;        mInstrumentation = instr;        mToken = token;        mAssistToken = assistToken;        mIdent = ident;        mApplication = application;        mIntent = intent;        mReferrer = referrer;        mComponent = intent.getComponent();        mActivityInfo = info;        mTitle = title;        mParent = parent;       ....        mWindow.setWindowManager(               (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),                mToken, mComponent.flattenToString(),               (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);        if (mParent != null) {            mWindow.setContainer(mParent.getWindow());       }        mWindowManager = mWindow.getWindowManager();        mCurrentConfig = config;       ....   }

然后通过mInstrumentation.callActivityOnCreate回调Activity的onCreate(),onPostCreate()完成Launch流程。