天天看點

Android 源碼分析 (四) Activity 啟動

Android  啟動類的作用

Instrumentation     完成對Application和Activity初始化和生命周期調用的工具類。用來監控系統與應用的互動。

ActivityThread     管理應用程序的主線程的執行。

ApplicationThread     用來實作ActivityManagerService與ActivityThread之間的互動。在ActivityManagerService管理應用程序中的Activity時,通過ApplicationThread的代理對象與ActivityThread通訊。(繼承IApplicationThread.Stub)

ActivityClientRecord     在應用程式程序中啟動的每一個Activity元件都使用一個ActivityClientRecord對象來描述。并且儲存在ActivityThread類的成員變量mActivities中。

ActivityRecord     在AMS程序中,一個ActivityRecord對應一個Activity,儲存了一個Activity的所有資訊。這些ActivityRecord對象對應于App程序中的ActivityClientRecord。

TaskRecord   任務棧,每一個TaskRecord都可能存在一個或多個ActivityRecord,棧頂的ActivityRecord表示目前可見的界面 。

ActivityStack    一個棧式管理結構,每一個ActivityStack都可能存在一個或多個TaskRecord,棧頂的TaskRecord表示目前可見的任務。

ActivityStackSupervisor     管理着多個ActivityStack,但目前隻會有一個擷取焦點(Focused)ActivityStack。 ProcessRecord     記錄着屬于一個程序的所有ActivityRecord,運作在不同TaskRecord中的ActivityRecord可能是屬于同一個 ProcessRecord。

ActivityManagerService     AMS主要負責系統中四大元件的啟動、切換、及程序的管理和排程等工作,Android8.0中AMS繼承IActivityManager.Stub。

系統程序、系統桌面 Launcher 程序、應用程式程序的啟動過程,那麼接下來點選系統桌面圖示就該進入到應用程式程序的根 Activity了,

應用程式根 Activity 啟動過程

Activity 啟動過程分為 2 種,一種是應用程式根 Activity 的啟動也就是在 XML 布局中有該配置的屬性,

<action android:name="android.intent.action.MAIN"/>
           

第二種就是我們程式中調用 startActivity 啟動。不過這 2 種在最後源碼中的調用幾乎一樣,可以這樣說隻要了解了第一種,那麼第二種了解起來就輕松多了。下面我們先來分析第一種。

 一 Launcher 請求 AMS 過程

我們點選某個應用的快捷圖示的時候,就會通過 Launcher 請求 AMS 來啟動該應用程式。

Launcher 請求 AMS 的時序圖如下:

Android 源碼分析 (四) Activity 啟動

我們點選應用圖示的時候,就會調用 Launcher 的 startActivitySafely 函數

//Launcher.java
    public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
        if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {
            Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
            return false;
        }
       
         1. 為啟動應用的 Activity 添加一個新的任務棧
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (v != null) {
            intent.setSourceBounds(getViewBounds(v));
        }
        try {
            if (Utilities.ATLEAST_MARSHMALLOW
                    && (item instanceof ShortcutInfo)
                    && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                     || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                    && !((ShortcutInfo) item).isPromise()) {
                // Shortcuts need some special checks due to legacy reasons.
                startShortcutIntentSafely(intent, optsBundle, item);
            } else if (user == null || user.equals(Process.myUserHandle())) {
                // Could be launching some bookkeeping activity
                2處調用 Activity 内部的函數 startActivity
                startActivity(intent, optsBundle);
            } else {
                LauncherAppsCompat.getInstance(this).startActivityForProfile(
                        intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
            }
            return true;
        } catch (ActivityNotFoundException|SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
        }
        return false;
    }
           

2 處調用 Activity 内部的函數 startActivity,詳細代碼如下:

//Activity.java
    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
       
        if (options != null) {
        有傳參行為,調用 Activity startActivityForResult 函數,将參數傳遞下去

            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }
           

在 Activity startActivity 函數中最終會調用 startActivityForResult 函數

//Activity.java
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
     
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);

          1
         Instrumentation:主要用來監控應用程式和系統的互動
         調用 Instrumentation 的 execStartActivity 函數。
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
               2  Activity onActivityResult 回調
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
          ...
        } else {
            ...
        }
    }
           

我們看注釋 1 的源碼實作,如下:

//Instrumentation.java
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
      	1 
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ....
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
           2  
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
           

總結上面代碼 

1 拿到 IApplicationThead . aidl 程序間通信方式

2  AMS 代理對象 IActivityManager .aidl ,調用 aidl 中的 startActivity 函數最後在 AMS 中

我們來看下 ActivityManager.getService() 實作,代碼如下:

//ActivityManager.java
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                  	1 
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                  	2 
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
           

getService 函數調用 IActivityManagerSingleton 的 get 函數 ,IActivityManagerSingleton 是一個 Singleton 類

1 得到名為“activity”的Service引用,也就是IBinder類型AMS的引用

2 注釋2處将它轉換成IActivityManage 的類型的對象

二 AMS 到 ApplicationThread 的調用過程 

 AMS 到 ApplicationThread 的調用流程,時序圖如下:

Android 源碼分析 (四) Activity 啟動

AMS 中的 startActivity 函數,代碼如下:

//AMS.java

    /**
     * Instrumentation startActivity 傳遞過來的
     * @param caller
     * @param callingPackage
     * @param intent
     * @param resolvedType
     * @param resultTo
     * @param resultWho
     * @param requestCode
     * @param startFlags
     * @param profilerInfo
     * @param bOptions
     * @return
     */
    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        /**
         * 調用内部 startActivityAsUser 函數
         */
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }


    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        1

        enforceNotIsolatedCaller("startActivity");
        2 
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        3
        
 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null,
                "startActivityAsUser");
    }
           

在 AMS 的 startActivity 函數中調用内部的 startActivityAsUser 函數,在該函數中我們主要做了 3 個步驟

  1. 判斷調用者程序是否被隔離
  2. 檢查調用者權限
  3. 調用 ActivityStarter 的 startActivityMayWait 函數,啟動 Activity 的理由

startActivityMayWait 函數中需要注意倒數第二個參數 TaskRecord,代表啟動的 Activity 任務棧

//ActivityStarter.java
    final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask, String reason) {

...
            /**
             * ActivityStarter 是加載 Activity 控制類,會搜集所有的邏輯來決定如果将 Intent 和 Flags 轉換為 Activity ,并将Activity 和 Task 以及 Stack 相關聯。
             */
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask, reason);


...
}
           

ActivityStarter 它是加載 Activity 的控制類,會收集所有的邏輯來決定如果将 Intent 和 Flag 轉為 Activity ,并将 Activity 和 Task 以及 Stack 相關聯。

看内部 startActivityLocked 方法

//ActivityStarter.java
    int startActivityLocked(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,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask, String reason) {

        1. 判斷啟動的理由不為空
        if (TextUtils.isEmpty(reason)) {
            throw new IllegalArgumentException("Need to specify a reason.");
        }
        mLastStartReason = reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();
        mLastStartActivityRecord[0] = null;

       2. 繼續調用目前類裡面的 startActivity 函數
        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                container, inTask);

        if (outActivity != null) {
            // mLastStartActivityRecord[0] is set in the call to startActivity above.
            outActivity[0] = mLastStartActivityRecord[0];
        }
        return mLastStartActivityResult;
    }
           

繼續調用 startActivity 函數,代碼如下:

//ActivityStarter.java

    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,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
 ...
        1
        if (caller != null) {
            /**
             * 得到 Launcher 所在程序
             */
            callerApp = mService.getRecordForAppLocked(caller);
            /**
             *  獲得 Launcher 程序的 pid , uid
             */
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller
                        + " (pid=" + callingPid + ") when starting: "
                        + intent.toString());
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }
			...

         2
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, container, options, sourceRecord);
        if (outActivity != null) {
           3
            outActivity[0] = r;
        }

        if (r.appTimeTracker == null && sourceRecord != null) {
            // If the caller didn't specify an explicit time tracker, we want to continue
            // tracking under any it has.
            r.appTimeTracker = sourceRecord.appTimeTracker;
        }

       ...

        doPendingActivityLaunchesLocked(false);

       4 
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }
           

總結 ActivityStarter startActivity 做了哪些事情

1  判斷上層傳遞過來的 IApplicationThread 是否為空,因為這裡我們是一路傳遞下來的,是以不為空。

2注釋 1.1 處調用 AMS 的 getRecordForAppLocked 函數得到的代表 Launcher 程序的 callerApp 對象,它是 ProcessRecord 類型的, ProcessRecord 用于描述一個應用程式程序。

3 建立 ActivityRecord 類,用于描述一個 Activity 所有的資訊。

4 将建立出來 ActivityRecord 指派給 ActivityRecord 數組的第一個位置,繼續調用内部重載函數 startActivity 把 啟動 Activity 的描述資訊也一并傳遞過去

接下來我們看注釋 4 的代碼實作

//ActivityStarter.java
    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        int result = START_CANCELED;
        try {
            /**
             * 拿到 WMS
             */
            mService.mWindowManager.deferSurfaceLayout();
            1 
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        } finally {
            ....

        return result;
    }
           

接着調用 ActivityStarter 内部函數 startActivityUnchecked

//ActivityStarter.java
    /**
     * 主要處理 棧管理相關的邏輯
     * @param r
     * @param sourceRecord
     * @param voiceSession
     * @param voiceInteractor
     * @param startFlags
     * @param doResume
     * @param options
     * @param inTask
     * @param outActivity
     * @return
     */
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        ...
          
       1
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
           2 
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
            setTaskToCurrentTopOrCreateNewTask();
        }
        ...
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                ...
                mWindowManager.executeAppTransition();
            } else {
               ...
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
               3
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
       ...
        return START_SUCCESS;
    }
           

總結上述方法 

1. 判斷條件是否滿足,是否是 新建立的任務棧模式

2 建立新的 TaskRecord ,用來描述 Activity 任務棧

3 調用 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked 函數

Flag 設定為 FLAG_ACTIVITY_NEW_TASK 模式,這樣注釋 1 條件滿足,接着執行注釋 2 處的 setTaskFromReuseOrCreateNewTask 函數,其内部會建立一個新的 TaskRecord ,用來描述一個 Activity 的任務棧

現在來看3處的代碼

//ActivityStackSupervisor.java
    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        //需要啟動的目标棧不為空,并且啟動的棧跟需要啟動棧一樣就執行
        if (targetStack != null && isFocusedStack(targetStack)) {
            
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
         1
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
         2
        if (r == null || r.state != RESUMED) {
            3
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.state == RESUMED) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }
        return false;
    }
           

1. 擷取需要啟動的 Activity 所在棧的棧頂 不是處于停止狀态的 ActivityRecord

2 如果 ActivityRecord 不為 null,或者要啟動的 Activity 的狀态不是Resumed 狀态

3 這裡主要是擷取正在運作的任務棧,如果擷取到的棧不為空并且不是 Resumed 狀态 ,那麼就代表即将要啟動一個新的 Activity

接着往下看 注釋3處的代碼

//ActivityStack.java
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
       ...
        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            1
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        mStackSupervisor.checkReadyForSleepLocked();

        return result;
    }
           

把 mStackSupervisor.inResumeTopActivity 設定為 true ,然後繼續調用内部 resumeTopActivityInnerLocked 函數,代碼如下:

//ActivityStack.java
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
       ...

           1
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }
           

接着看 ActivityStackSupervisor的 startSpecificActivityLocked 方法

//ActivityStackSupervisor.java
    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        1
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.getStack().setLaunchTime(r);

       2
        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                   
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                3
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
               ...
            }

        }
				//4. 
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }
           

總結ActivityStackSupervisor的 startSpecificActivityLocked 方法

1. 擷取即将啟動的 Activity 所在的應用程式程序

2.判斷要啟動的 Activity 所在的應用程式程序

3.如果已經正在運作調用 realStartActivityLocked 函數

4會通知 AMS 與 Zygote 通信請求建立一個新的程序

//ActivityStackSupervisor.java
    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
			
      ...
            
        /*** 
        			這裡的 app.thread 代表的是 IApplicationThread ,調用它内部 scheduleLaunchActivity 函								數,
             * 它的實作在 ActivityThread 的内部類 ApplicationThread ,其中 ApplicationThread 繼承了 IApplicationThread.Stub.,
             * app 指的是Activity 所在的應用程式程序。
             */

            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    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, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);

            ...

        } catch (RemoteException e) {
            ...

        return true;
    }
           

app.thread 指的就是 IApplicationThread, 它的實作類在 ActivityThread 的内部類,其中 ApplicationThread 繼承了 IApplicationThread.Stub。app 指的是傳入的要啟動的 Activity 所在應用程式程序,是以,這段代碼指的就是要在目标應用程序進行啟動 Activity 。目前代碼邏輯運作在 AMS 所在的 SystemServer 程序中,通過 ApplicationThread 來與應用程式程序進行 Binder 通信,換句話說,ApplicationThread 是 SystemServer 和應用程式程序通信的中間人。

到這裡下面就該看 ActivityThread 類裡面執行 Activity 任務了,

三  ActivityThread 啟動 Activity 過程

先來看一下 ActivityThread 啟動 Activity 的時序圖

Android 源碼分析 (四) Activity 啟動

ActivityThread 在應用程式程序建立成功後會運作在目前程序的主線程中。scheduleLaunchActivity 代碼如下:

//ActivityThread.java
public final class ActivityThread {
 ...
   
 private class ApplicationThread extends IApplicationThread.Stub {  
   
 ...
 
 private class ApplicationThread extends IApplicationThread.Stub {
   
 ....
   
         /**
         * Launcher 點選應用圖示啟動對應的應用 .... -> ActivityStackSupervisor . realStartActivityLocked 函數調用
         * @param intent
         * @param token
         * @param ident
         * @param info
         * @param curConfig
         * @param overrideConfig
         * @param compatInfo
         * @param referrer
         * @param voiceInteractor
         * @param procState
         * @param state
         * @param persistentState
         * @param pendingResults
         * @param pendingNewIntents
         * @param notResumed
         * @param isForward
         * @param profilerInfo
         */
        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);
           1. 調用内部 sendMessage 函數,将啟動 Activity 的資訊封裝成 ActivityClientRecord 對象,然後跟 H.LAUNCH_ACTIVITY 一起傳遞下去
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
   
 ...
 }
   
 ...
}
           
//ActivityThread.java  
	private void sendMessage(int what, Object obj) {
         調用内部重載函數 what = H.LAUNCH_ACTIVITY
        sendMessage(what, obj, 0, 0, false);
    }
           
//ActivityThread.java

    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);
        }
       2. 通過 H 的 Handler 将 what = H.LAUNCH_ACTIVITY 消息 what 發送出去
        mH.sendMessage(msg);
    }
           

mH 是 AcitivtyThread 非靜态内部類,它繼承自 Handler,來看下 H 的實作

//ActivityThread.java
public final class ActivityThread {
  
//應用程式程序 主線程 H 
final H mH = new H(); 
  
  ......
    
 private class H extends Handler {
 
  //啟動 Activity 标志
  public static final int LAUNCH_ACTIVITY         = 100;
    
    public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                1 
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    2
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                   3
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    4 
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                
                
               ....
  ......
}
           

我們看下H 主要幹了什麼

1. 收到發送過來 LAUNCH_ACTIVITY 标志的消息

2 拿到封裝啟動 Activity 資訊的 ActivityClientRecord 類

3 通過 getPackageInfoNoCheck 函數獲得 LoadedApk 類型的對象并指派給 ActivityClientRecord 的成員變量 packageInfo。 * 應用程式程序要啟動 Activity 時,需要将該 Activity 所屬的 APK 加載進來,而 LoadedApk 就是用來描述已加載的 APk 檔案的

4 調用内部 handleLaunchActivity

接着往下看 注釋4 處的代碼 handleLaunchActivity

//ActivityThread.java
    /**
     *
     *啟動 Activity
     * @param r
     * @param customIntent
     * @param reason
     */
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
       ...

        1. 實施啟動 Activity 的執行個體
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
          2. 将 Activity 的狀态設定為 Resume
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

         ...
        } else {
           
            try {
               
                ActivityManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }
           

接着往下看  performLaunchActivity 

//ActivityThread.java


    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

      1. 通過封裝啟動 Activity 資訊類 ActivityClientRecord 來擷取到 ActivityInfo
        ActivityInfo aInfo = r.activityInfo;
       2. 如果 r.packageInfo == null 就擷取 LoadedApk 執行個體
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        3. 通過封裝啟動 Activity 資訊類 ActivityClientRecord 來擷取啟動 Activity 元件的 ComponentName
        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);
        }
         4. 建立Activity 中的上下文環境
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
           5. 調用 Instrumentation.newActivity 函數 ,内部通過 ClassLoader 類加載器來建立 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);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            6. 得到 Application 對象
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            if (activity != null) {

                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                appContext.setOuterContext(activity);
               7. 将 appContext 等對象依附在 Activity 的 attach 函數中,進行 Activity  attach 初始化
                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);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                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 {
                 8. 内部調用 Activity 的 onCreate 方法
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }
           

拿到啟動 Activity 元件 Component 的資訊,通過 Instrumentation 類的 newActivity 函數,内部是通過 ClassLoader 的 loadClass 執行個體化了 Activity, 拿到 Application 進行與 Activity 綁定,最後調用 Instrumentation 函數的 callActivityOnCreate 執行了 Activity onCreate 生命周期,到這裡 Launcher 點選應用圖示到啟動應用程式的根 Activity 已經啟動了 至此Activity的啟動分析完了。

繼續閱讀