Android之9.0Activity啓動流程(二)

注:下列源碼均基於9.0,可通過下列方式下載本文相關源碼到本地:

  • git clone https://aosp.tuna.tsinghua.edu.cn/platform/frameworks/base

參考博客:如何下載和閱讀Android源碼

前言

在上一篇文章Android之9.0Actvitiy啓動流程(一)中我們已經分析了根Activity啓動時所需的應用進程是如何創建的,並且當前應用進程已經啓動了ActivityThread的main方法,所以這篇文章主要圍繞下列內容展開來講解:

  • 應用進程綁定到AMS
  • AMS發送啓動Activity的請求
  • ActivityThread的Handler處理啓動Activity的請求

一、應用進程綁定到AMS

1. 時序圖

[外鏈圖片轉存失敗(img-DlmoMg47-1566527233633)(F:\md\開發藝術探索\images\啓動流程\應用進程綁定到AMS.png)]

2. 詳細過程

在前面一篇我們知道當Zygote進程孵化出應用進程後會執行ActivityThread的main方法,所以我們先看看main方法裏的代碼。

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

    public static void main(String[] args) {
        ....
		//創建主線程的Looper以及MessageQueue
        Looper.prepareMainLooper();
        ...
        //AMS綁定ApplicationThread對象,即應用進程綁定到AMS
        thread.attach(false, startSeq);
		//開啓主線程的消息循環
        Looper.loop();
        ...
    }

在這裏我們就不再詳細分析prepareMainLooper和loop方法,其主要功能就是準備好主線程的Looper以及消息隊列,最後再開啓主線程的消息循環。如果不懂的可以看看前面的博客Handler機制中對這兩個方法的分析,在這裏我們將重點分析attach這個方法。

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

    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 {
				//AMS綁定ApplicationThread對象
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            //垃圾回收觀察者
            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                                + " total=" + (runtime.totalMemory()/1024)
                                + " used=" + (dalvikUsed/1024));
                        mSomeActivitiesChanged = false;
                        try {
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            });
        } 
        ...
    }

可以看到由於在ActivityThread的attach中我們傳入的是false,故在attach方法中將執行!system裏的代碼,通過調用AMS的attachApplication來將ActivityThread中的內部類ApplicationThread對象綁定至AMS,這樣AMS就可以通過這個代理對象 來控制應用進程。接着爲這個進程添加垃圾回收觀察者,每當系統觸發垃圾回收的時候就在run方法中計算應用使用了多大的內存,如果超過總量的3/4就嘗試釋放內存。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }


    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
			....
			    //將應用進程的ApplicationThread對象綁定到AMS,即AMS獲得ApplicationThread的代理對象
                thread.bindApplication(processName, appInfo, providers,
                        app.instr.mClass,
                        profilerInfo, app.instr.mArguments,
                        app.instr.mWatcher,
                        app.instr.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, isAutofillCompatEnabled);
          

        boolean badApp = false;
        boolean didSomething = false;
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
				//啓動Activity
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        .....
    }

在AMS的attachApplication方法中調用了attachApplicationLocked進行綁定,從上面代碼可以發現attachApplicationLocked中有兩個重要的方法:thread.bindApplication和mStackSupervisor.attachApplicationLocked(app)。thread.bindApplication中的thread其實就是ActivityThread裏ApplicationThread對象在AMS的代理對象,故此方法將最終調用ApplicationThread的bindApplication方法。而mStackSupervisor.attachApplicationLocked(app)主要是AMS啓動Activity的作用(在下列AMS發送啓動Activity的請求會分析到)。在這裏我們先看看ApplicationThread的bindApplication方法。

frameworks/base/core/java/android/app/ActivityThread.ApplicationThread

       public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, boolean autofillCompatibilityEnabled) {

          	....
			//向H發送綁定ApplicationThread對象的消息
            sendMessage(H.BIND_APPLICATION, data);
        }

    void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        ...
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

可以發現上面其實就是Handler機制的應用,mH其實就是H類型的,所以bindApplication主要就是向ActivityThread的Handler,即H發送綁定的消息。

frameworks/base/core/java/android/app/ActivityThread.H

	//線程所需要的Handler,內部定義了一組消息類型,主要包括四大組件的啓動和停止過程
    class H extends Handler {
        public static final int BIND_APPLICATION        = 110;
        ...
        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;
                ...
        }
    }

這個H其實就是當前線程,也可以說是主線程ActivityThread的Handler,內部定義了一組消息類型,包括了四大組件的啓動和停止過程。通過Handler機制我們知道在H的handleMessage中會處理髮送給H的消息,在這裏將調用handleBindApplication方法。

frameworks/base/core/java/android/app/ActivityThread

    @UnsupportedAppUsage
    private void handleBindApplication(AppBindData data) {

        ....
        final InstrumentationInfo ii;
        if (data.instrumentationName != null) {
            try {
                ii = new ApplicationPackageManager(null, getPackageManager())
                        .getInstrumentationInfo(data.instrumentationName, 0);
            } 
            ...
        } else {
            ii = null;
        }
        ....
        // Continue loading instrumentation.
        if (ii != null) {
            .....
        } else {
            mInstrumentation = new Instrumentation();
            mInstrumentation.basicInit(this);
        }
        ....
        try {
            // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
            app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;
            try {
                //調用Application的onCreate的方法
                //故Application的onCreate比ActivityThread的main方法慢執行
                //但是會比所有該應用Activity的生命週期先調用,因爲此時的Activity還沒啓動
                mInstrumentation.callApplicationOnCreate(app);
            }
            ...
        } 
    }

二、AMS發送啓動Activity的請求

應用進程綁定後,隨之就得啓動Activity,那麼得向誰發送啓動Activity得到請求呢?顯而易見,當然是向主線程即ActivityThread發送啓動Activity的請求。下面就讓我們一探究竟!

1. 時序圖

[外鏈圖片轉存失敗(img-UaWral2q-1566527233635)(F:\md\開發藝術探索\images\啓動流程\AMS發送啓動Activity的請求.png)]

2. 詳細過程

現在當前進程已經綁定到了AMS,綁定後呢?回憶一下,上面對AMS的attachApplicationLocked方法分析時,重點提到了兩個方法,其中ApplicationThread的bindApplication方法我們分析應用進程是如何綁定到AMS的,沒錯!另外一個方法mStackSupervisor.attachApplicationLocked(app)就是用來啓動Activity的,現在讓我們來看看。

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ...
            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                ....
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
                    if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
						    //真正啓動Activity,也是普通Activity的啓動過程
                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                             ...
                        }
                    }
                }
            }
        }
        return didSomething;
    }

attachApplicationLocked會調用realStartActivityLocked方法,如下。

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
                .....
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
			    //添加callback,首先會執行callback中的方法
                 //此時的ActivityLifecycleItem爲LaunchActivityItem
                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, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                        profilerInfo));

                //判斷此時的生命週期是resume還是pause
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                //設置當前的生命週期
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // mService爲AMS對象,getLifecycleManager得到ClientLifecycleManager
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        	    ......
            } 
			....
        return true;
    }

在realStartActivityLocked方法中爲ClientTransaction對象添加LaunchActivityItem的callback,然後設置當前的生命週期狀態,由於我們是根Activity的啓動,很顯然這裏的生命週期爲ResumeActivityItem,最後調用ClientLifecycleManager.scheduleTransaction方法執行。我們繼續追蹤下去!

frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java

    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            transaction.recycle();
        }
    }

從上面代碼中可以看出,由於transaction爲ClientTransaction類型,故接下去將執行ClientTransaction的schedule方法

frameworks\base\core\java\android\app\servertransaction\ClientTransaction.java

    public void schedule() throws RemoteException {
        //1.mClient是IApplicationThread類型,
        //2.ActivityThread的內部類ApplicationThread派生這個接口類並實現了對應的方法
        //3.ActivityThread實際調用的是他父類ClientTransactionHandler的scheduleTransaction方法。
        mClient.scheduleTransaction(this);
    }

mClient是IApplicationThread類型,通過名字和閱讀源碼我們可以知道ApplicationThread會實現該類型,所以這裏調用的應該是ApplicationThread的scheduleTransaction方法,我們知道ApplicationThread是ActivityThread的內部類,所以通過閱讀ActivityThread源碼你會發現在這個類中並沒有實現scheduleTransaction這個方法,難道分析錯了????

聰明的你應該想到了,既然在當前類找不到這個方法,只能去找父類尋求幫助了,果然薑還是老的辣,在ActivityThread的父類ClientTransactionHandler中我們找到了這個scheduleTransaction方法。如下

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

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    abstract void sendMessage(int what, Object obj);

看到這是不是突然覺得很熟悉,不急,我們一步一步來分析!在這個方法中會調用sendMessage方法,而在ClientTransactionHandler類中該sendMessage方法爲抽象方法,其具體實現在子類ActivityThread中,如下

frameworks/base/services/core/java/com/android/server/am/ActivityThread.java

    void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

上面的代碼很容易理解,在ActivityThread的sendMessage中會把啓動Activity的消息發送給mH,而mH爲H類型,其實就是ActivityThread的Handler。到這裏AMS就將啓動Activity的請求發送給了ActivityThread的Handler。

三、ActivityThread的Handler處理啓動Activity的請求

1. 時序圖

[外鏈圖片轉存失敗(img-Ohks0kHI-1566527233637)(F:\md\開發藝術探索\images\啓動流程\ActivityThread的Handler處理啓動Activity的請求.png)]

2. 詳細過程

既然發送了啓動Activity的消息,那麼就得ActivityThread當然得處理這個消息,我們知道Handler機制,如果是通過sendMessage的方法發送消息的話,應該是在Handler的handleMessage處理消息,在這裏也同樣如此,ActivityThread的Handler就是H,讓我們來看看H的handleMessage,看看是否能找到EXECUTE_TRANSACTION消息的處理.

frameworks/base/core/java/android/app/ActivityThread.H

        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;
                ......
				//處理事務,處理活動的啓動,生命週期的轉化等	
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
					//切換Activity的狀態
                    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;
                ....
            }
            ...
        }

果真如此,我們H接受到AMS發來的EXECUTE_TRANSACTION消息後,將調用TransactionExecutor.execute方法來切換Activity狀態。

frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java

    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
        //先執行callbacks,當根活動首次啓動時會有callback,callback會執行onCreate方法
        //其它活動切換狀態時沒有callback
        executeCallbacks(transaction);
        //改變活動的生命週期狀態
        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }

在execute方法中重點關注兩個方法:executeCallbacks,由於我們現在分析的是根Activity的啓動流程,從上面也可以知道此時的callback是不爲null的,所以會執行executeCallbacks,最終會執行Activity的onCreate方法.此時根Activity就已經啓動成功了。executeLifecycleState方法是用來改變活動的生命週期狀態的,如果是根Activity的啓動,最終將會執行onStart和onResume方法。下面來分析這兩個方法

2.1 執行onCreate方法

來看看executeCallbacks這個方法。

frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java

    @VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null) {
            // No callbacks to execute, return early.
            return;
        }
        ......
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            //此時item爲LaunchActivityItem
            final ClientTransactionItem item = callbacks.get(i);
            ......
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ......
        }
    }

從上面的分析我們知道根Activity啓動時這個callback的ClientTransactionItem爲LaunchActivityItem,所以會執行LaunchActivityItem的execute方法。

frameworks\base\core\java\android\app\servertransaction\LaunchActivityItem.java

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

上面的client爲ActivityThread,所以會繼續調用ActivityThread的handleLaunchActivity方法,如下。

    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        mSomeActivitiesChanged = true;
        //啓動Activity
        final Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            .....
        } else {
            //如果出現錯誤就通知AMS停止活動
            try {
				//停止Activity
                ActivityManager.getService()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }

        return a;
    }

在上述方法中將調用performLaunchActivity來啓動活動,如下

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        //ActivityInfo用於存儲代碼和AndroidManifes設置的Activity和receiver節點信息,
        //比如Activity的theme和launchMode
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
			//獲取APK文件的描述類LoadedApk
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }
		//獲取要啓動的Activity的ComponentName類,ComponentName類中保存了該Activity的包名和類名
        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

		
        //創建要啓動Activity的上下文環境
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();

		    //用類加載器來創建該Activity的實例
            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);
            }
        }
        ...

        try {
			//創建Application,makeApplication會調用Application的onCreate方法
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ...
            if (activity != null) {
                ....
                //初始化Activity,創建Window對象(PhoneWindow)並實現Activity和Window相關聯
                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);

                ....
                //設置主題    
                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);
                }
                ....
            }

			//設置生命週期爲onCreate
            r.setState(ON_CREATE);
        } 
        ...
        return activity;
    }

該方法代碼很多,要乾的事情也挺多的,並且都很重要,通過註釋應該可以知道這個方法的任務,當幹完所有事後得將當前的生命週期設置爲ON_CREATE。我們重點關注啓動活動的代碼mInstrumentation.callActivityOnCreate,可以知道在這裏將會調用Instrumentation的callActivityOnCreate來啓動活動。

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

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

而callActivityOnCreate將調用Activity的performCreate,如下

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

    final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }

    @UnsupportedAppUsage
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ....
		//調用Activity的onCreate,根Activity啓動成功
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ...
    }

看得到這眼淚是否嘩啦啦啦的流下了,終於看到熟悉的東西了,在Activity的performCreate中將執行onCreate,也就是我們在開發中所熟悉的onCreate,“終於等到你,還好我們沒放棄”,講到這,根Activity就已經啓動了,我們的萬里長征也應該結束了,但是身爲萬里長征的首席指揮官,總不能一結束就撒手不管吧。所以讓我們繼續來看看結束後的維護工作。

2.2 執行onStart方法

從上面分析中我們知道onCreate已經被調用,且生命週期的狀態是ON_CREATE,故executeCallbacks已經執行完畢,所以開始執行executeLifecycleState方法。如下

frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
        ....
        // 執行當前生命週期狀態之前的狀態
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

        //切換狀態
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

在executeLifecycleState方法中,會先執行cycleToPath,從上面的分析我們已經知道當根Activity啓動時,此時的lifecycleItem爲ResumeActivityItem,故調用lifecycleItem.getTargetState時將得到ON_RESUME狀態,讓我們來瞧瞧cycleToPath方法。

    private void cycleToPath(ActivityClientRecord r, int finish,
            boolean excludeLastState) {
        final int start = r.getLifecycleState();
        log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path);
    }

由於onCreate方法已經執行,所以start爲ON_CREATE,而finish爲上面傳遞的ON_RESUME,excludeLastState是否移除最後的狀態爲true。讓我們來看看getLifecyclePath這個方法

frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java

    public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
        ...
        if (finish >= start) {
            // 添加start到finish之間的週期狀態
            for (int i = start + 1; i <= finish; i++) {
                mLifecycleSequence.add(i);
            }
        } 
        ...
        // 根據需求移除最後的狀態
        if (excludeLastState && mLifecycleSequence.size() != 0) {
            mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
        }

        return mLifecycleSequence;
    }

public abstract class ActivityLifecycleItem extends ClientTransactionItem {
    .....
    public static final int UNDEFINED = -1;
    public static final int PRE_ON_CREATE = 0;
    public static final int ON_CREATE = 1;
    public static final int ON_START = 2;
    public static final int ON_RESUME = 3;
    public static final int ON_PAUSE = 4;
    public static final int ON_STOP = 5;
    public static final int ON_DESTROY = 6;
    public static final int ON_RESTART = 7;
    ...
}

在getLifecyclePath這個方法我們知道start爲ON_CREATE,finish爲ON_RESUME,那麼如何知道start和finish的大小關係呢?在ActivityLifecycleItem中我們可以發現這些狀態的定義,從定義中可以發現finish>=start,所以我們只關注這部分的邏輯處理,可以發現ON_CREATE和ON_RESUME中間還有ON_START這個狀態,所以mLifecycleSequence將添加ON_START和ON_RESUME狀態,但是又因爲excludeLastState爲true,所以最後會移除掉ON_RESUME狀態,故返回的類型只包含ON_START狀態。故cycleToPath方法中的path中將只包含ON_START狀態,然後繼續執行performLifecycleSequence方法。

    private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            log("Transitioning to state: " + state);
            switch (state) {
                .....
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break;
                 ......
            }
        }
    }

因爲path只包含ON_START狀態,所以只執行ActivityThread的handleStartActivity方法。

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

	public void handleStartActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        ...
        // Start
        activity.performStart("handleStartActivity");
        r.setState(ON_START);
        ...
    }

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

final void performStart(String reason) {
    ...
     mInstrumentation.callActivityOnStart(this);
    ...
}

frameworks/base/core/java/android/app/Instrumentation.java

    public void callActivityOnStart(Activity activity) {
        activity.onStart();
    }

從上面可以發現ActivityThread.handleStartActivity經過多次跳轉最終會執行activity.onStart方法,至此cycleToPath方法執行完畢。

2.3 執行onResume方法

讓我們回到executeLifecycleState這個方法,執行完cycleToPath方法後將執行lifecycleItem.execute,即ResumeActivityItem的execute方法。

frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java

    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        //此client爲ActivityThread
        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

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

    @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        ...
        // TODO Push resumeArgs into the activity for consideration
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        ...
        Looper.myQueue().addIdleHandler(new Idler());
        ...
    }

    public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
            String reason) {
        ...
        try {
            ...
            r.activity.performResume(r.startsNotResumed, reason);
            r.state = null;
            r.persistentState = null;
            //設置當前狀態爲ON_RESUME
            r.setState(ON_RESUME);
        } 
        ...
        return r;
    }

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

    final void performResume(boolean followedByPause, String reason) {
        performRestart(true /* start */, reason);
        ...
        // mResumed is set by the instrumentation
        mInstrumentation.callActivityOnResume(this);
        ...
    }

frameworks/base/core/java/android/app/Instrumentation.java

    public void callActivityOnResume(Activity activity) {
        activity.mResumed = true;
        activity.onResume();
        ...
    }

可以發現其實執行onCreate,onStart,onResume的流程大致上是類似的,通過多次調用最終將會調用Activity的onResume方法,至此Activity真正啓動完畢!

總結

理解根Activity的啓動流程至關重要,在此次分析根Activity的啓動流程中對Activity的生命週期也有了更深的瞭解,由於在分析過程中是基於Android9.0的,與之前的版本有些改動,有時候會陷入源碼的沼澤中,越掙扎陷的越深。所以我覺得我們應該藉助源碼來把握整體流程,但又不能糾結於讀懂源碼中的任何代碼,這是不太現實的。

兩篇文章結合起來,我們可以得知Activity的啓動的整體流程:

1. Launcher進程請求AMS
2. AMS發送創建應用進程請求
3. Zygote進程接受請求並孵化應用進程
4. 應用進程啓動ActivityThread
5. 應用進程綁定到AMS
6. AMS發送啓動Activity的請求
7. ActivityThread的Handler處理啓動Activity的請求

參考博客:

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