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流程。