Activity啓動源碼分析-基於Android10(一)

前言

之前對於啓動Activity有所瞭解,但是自覺瞭解不深,而且很容易忘記,本着"好記性不如爛筆頭“這裏記錄下啓動流程。本文章參考Android Open Source Project

總流程圖
在這裏插入圖片描述

  • Instrumentation
    負責調用Activity和Application生命週期。
  • ActivityTaskManagerService
    負責Activity管理和調度等工作。android10中新增的
  • ActivityManagerService
    負責管理四大組件和進程,包括生命週期和狀態切換。
  • ActivityTaskManagerInternal
    ActivityTaskManagerService對外提供的一個抽象類,真正的實現在ActivityTaskManagerService#LocalService
  • ActivityThread
    管理應用程序進程中主線程的執行
  • ActivityStackSupervisor
    負責所有Activity棧的管理
  • TransactionExecutor
    主要作用是執行ClientTransaction
  • ClientLifecycleManager
    生命週期的管理調用

Activity啓動

在啓動Activity的時候,無論是點擊桌面的圖標,還是自己寫的App中啓動Activity,最後都是歸結到Activity的startActivityForResult方法。其實點擊桌面的圖標,也是依靠Launcher程序去打開Activity的,和我們使用startActivity方法去啓動Activity是沒有任何區別的。

frameworks\base\core\java\android\app\Activity.java

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            // 注意getApplicationThread方法
            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());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

無論如何startActivity,最後調用的是startActivityForResult方法。該方法最後調用了Instrumentation的execStartActivity方法。注意這句代碼:

mMainThread.getApplicationThread()

mMainThread實際上是ActivityThread類,而這個類就是傳說中的”主線程“。那麼getApplicationThread的值是什麼呢?通過系統源碼可以得知它是ActivityThread的內部類ApplicationThread

frameworks\base\core\java\android\app\ActivityThread.java

	@UnsupportedAppUsage
    public ApplicationThread getApplicationThread()
    {
        return mAppThread;
    }

ApplicationThread類繼承了IApplicationThread.Stub,熟悉AIDL的都知道,這個類是Android通過IApplicationThread.aidl自己生成的的類。
部分ApplicationThread代碼:

frameworks\base\core\java\android\app\ActivityThread.java

//...省略部分代碼
private class ApplicationThread extends IApplicationThread.Stub {
        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";

        public final void scheduleSleeping(IBinder token, boolean sleeping) {
            sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
        }

        public final void scheduleReceiver(Intent intent, ActivityInfo info,
                CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
                boolean sync, int sendingUser, int processState) {
            updateProcessState(processState, false);
            ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
                    sync, false, mAppThread.asBinder(), sendingUser);
            r.info = info;
            r.compatInfo = compatInfo;
            sendMessage(H.RECEIVER, r);
        }

        public final void scheduleCreateBackupAgent(ApplicationInfo app,
                CompatibilityInfo compatInfo, int backupMode, int userId) {
            CreateBackupAgentData d = new CreateBackupAgentData();
            d.appInfo = app;
            d.compatInfo = compatInfo;
            d.backupMode = backupMode;
            d.userId = userId;

            sendMessage(H.CREATE_BACKUP_AGENT, d);
        }
	//...省略部分代碼

而IApplicationThread.aidl恰恰是ActivityManagerService和App通訊的橋樑,後面的文章將會談到,順便一提,老版本用的是ActivityManagerService,新版本改爲ActivityTaskManagerService。
這裏的Instrumentation對象和ActivityThread對象都是通過Activity的attach方法獲取到的,Instrumentation對象是每創建一個Activity都會提供一個引用。

frameworks\base\core\java\android\app\ActivityThread.java

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
		//...省略部分代碼
		Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            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);
            }
        }
        //...省略部分代碼
        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,
                        r.assistToken);
                //...省略部分代碼
            }
}
frameworks\base\core\java\android\app\Activity.java

// 注意Instrumentation instr和IBinder token
// IBinder token就是IApplicationThread
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) {
        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;
        mIdent = ident;
        mApplication = application;
        mIntent = intent;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
        if (voiceInteractor != null) {
            if (lastNonConfigurationInstances != null) {
                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
            } else {
                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                        Looper.myLooper());
            }
        }

        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;

        mWindow.setColorMode(info.colorMode);

        setAutofillCompatibilityEnabled(application.isAutofillCompatibilityEnabled());
        enableAutofillCompatibilityIfNeeded();
    }

attach方法向Activity裏面添加了很多重要的參數,比如Context,ActivityThread,application等等。至於attach何時被執行,後面的文章將會給出詳細的分析。

下一篇:Activity啓動源碼分析-基於Android10(二)

參考文章:Activity的啓動流程-基於Android10源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章