Activity啟動流程 下篇(Android 10)

Activity啟動流程 上篇(Android 10)喉镰,我們從startActivity分析到了App進程的入口點ActivityThreadmain函數(shù)谓形。本篇藕届,我們將從這里開始竟秫,一步步分析晃虫,直到ActivityonCreate方法迄汛。

    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

        // Install selective syscall interception
        AndroidOs.install();

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
        // It will be in the format "seq=114"
        long startSeq = 0;
        if (args != null) {
            for (int i = args.length - 1; i >= 0; --i) {
                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
                }
            }
        }
        ActivityThread thread = new ActivityThread();

        //--------------------  
        thread.attach(false, startSeq);
        //--------------------  

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

如果大家稍微看過一些源碼,我相信對這段代碼還是非常熟悉的槽畔,Handler相關(guān)內(nèi)容我們不講栈妆,直接看thread.attach(false, startSeq)函數(shù):

    @UnsupportedAppUsage
    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ....
        } else {
            ....
        }

        ....
    }

ActivityManager.getService()就是ActivityManagerService,所以我們跨進程到了AMS中,并調(diào)用了attachApplication鳞尔,還把mAppThread 一個ApplicationThread句柄帶了過去嬉橙,這個很重要,大部分AMS調(diào)用App進行工作都是調(diào)用這個Ibinder句柄實現(xiàn)的铅檩,后面啟動Activity就是使用這個句柄的憎夷,ApplicationThreadActivityThread的一個子類。所以我們直接來看AMS的attachApplication方法:

    @Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        if (thread == null) {
            throw new SecurityException("Invalid application interface");
        }
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }

這里調(diào)用了attachApplicationLocked:

    ....
    //這里的thread昧旨,就是我們調(diào)用attachApplication傳入的參數(shù),即:ApplicationThread
    thread.bindApplication(....)
    ....
     
    //先講上面祥得,一會兒回來將這個兔沃。
    if (normalMode) {
        try {
            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }

這里首先調(diào)用了bindApplication又回到了App進程中:

        public final void bindApplication(String processName, ApplicationInfo appInfo,
            ....
            sendMessage(H.BIND_APPLICATION, data);
        }
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
            ....

然后是handleBindApplication

    private void handleBindApplication(AppBindData data) {
            ....
        try {
            // 創(chuàng)建Application
            app = data.info.makeApplication(data.restrictedBackupMode, null);

            try {
                // 調(diào)用Application的onCreate方法
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                      "Unable to create application " + app.getClass().getName()
                      + ": " + e.toString(), e);
                }
            }
    }

首先來看makeApplication

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        ....
        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);
            }
            //創(chuàng)建ContextImpl 
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            //創(chuàng)建Application
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        ....
    }

再來看mInstrumentation.callApplicationOnCreate(app)

    public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }

至此在App進程中bindApplication執(zhí)行完成,回到AMS執(zhí)行mAtmInternal.attachApplication(app.getWindowProcessController())级及,mAtmInternalActivityTaskManagerService乒疏,所以我們來看他的attachApplication方法:

        @Override
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                return mRootActivityContainer.attachApplication(wpc);
            }
        }

來到\frameworks\base\services\core\java\com\android\server\wm\RootActivityContainer.javaattachApplication方法:

    boolean attachApplication(WindowProcessController app) throws RemoteException {
            ....
                ....
                        try {
                            if (mStackSupervisor.realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                    + top.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                ....
            ....
        }
    }

終于到了大名鼎鼎的realStartActivityLocked,他在\frameworks\base\services\core\java\com\android\server\wm\ActivityStackSupervisor.java中:

        ....
                // Create activity launch transaction. 注意這個參數(shù)饮焦,將一直傳輸?shù)紸pp進程中
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);
                //將LaunchActivityItem添加到clientTransaction的callback列表中去怕吴,這里的intent,就是startActivity時傳入的Intent
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),...);

                // 設(shè)置Activity最終想要達到的狀態(tài)县踢,resume或者pause
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

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

mService.getLifecycleManager()獲取的是一個\frameworks\base\services\core\java\com\android\server\wm\ClientLifecycleManager.java對象转绷,調(diào)用它的scheduleTransaction方法:

    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }

ClientTransactionschedule方法:

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

這里mClientIApplicationThread,所以我們又再次回到了App進程:

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

這里我們調(diào)用的是ActivityThread父類ClientTransactionHandlerscheduleTransaction方法:

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;

這里調(diào)用了TransactionExecutorexecute

    public void execute(ClientTransaction transaction) {
        //循環(huán)遍歷回調(diào)請求的所有狀態(tài)并在適當?shù)臅r間執(zhí)行它們
        executeCallbacks(transaction);
        // 轉(zhuǎn)換到最終狀態(tài)
        executeLifecycleState(transaction);
    }

這里如果忘記了ClientTransaction 設(shè)置的內(nèi)容的話硼啤,可以回到上面的realStartActivityLocked查看:

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

這里執(zhí)行的肯定就是LaunchActivityItemexecute方法了

    @Override
    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);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

client就是ActivityThread议经,還記得它是繼承ClientTransactionHandler的嗎:

    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ....

        final Activity a = performLaunchActivity(r, customIntent);

        ....
    }
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        //反射創(chuàng)建Activity
        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 (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ....
        ....
    }

這里r.isPersistable()是指Activity是否需要持久化的Bundle,詳情請看這里 ,其實他們都會調(diào)用到Activity的create谴返,只是攜帶一個或者兩個參數(shù)的區(qū)別煞肾。一般的Activity都是調(diào)用第二個mInstrumentation.callActivityOnCreate(activity, r.state)

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

接下來的內(nèi)容都在Activity中了,比較簡單:

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

這樣嗓袱,就調(diào)用到了我們Activity的onCreate方法籍救,TransactionExecutorexecuteLifecycleState(transaction)會繼續(xù)調(diào)用onResume或者onPause方法。

總結(jié)如下:


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末渠抹,一起剝皮案震驚了整個濱河市蝙昙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逼肯,老刑警劉巖耸黑,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異篮幢,居然都是意外死亡大刊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缺菌,“玉大人葫辐,你說我怎么就攤上這事“橛簦” “怎么了耿战?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長焊傅。 經(jīng)常有香客問我剂陡,道長,這世上最難降的妖魔是什么狐胎? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任鸭栖,我火速辦了婚禮,結(jié)果婚禮上握巢,老公的妹妹穿的比我還像新娘晕鹊。我一直安慰自己,他們只是感情好暴浦,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布溅话。 她就那樣靜靜地躺著,像睡著了一般歌焦。 火紅的嫁衣襯著肌膚如雪飞几。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天同规,我揣著相機與錄音循狰,去河邊找鬼。 笑死券勺,一個胖子當著我的面吹牛绪钥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播关炼,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼程腹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了儒拂?” 一聲冷哼從身側(cè)響起寸潦,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎社痛,沒想到半個月后见转,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蒜哀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年斩箫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡乘客,死狀恐怖狐血,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情易核,我是刑警寧澤匈织,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站牡直,受9級特大地震影響缀匕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碰逸,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一弦追、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧花竞,春花似錦、人聲如沸掸哑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苗分。三九已至厌蔽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間摔癣,已是汗流浹背奴饮。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留择浊,地道東北人戴卜。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像琢岩,于是被迫代替她去往敵國和親投剥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容