Android源碼探究:Activity啓動流程完全解析

概述

本文主要內容是從源碼角度進行Activity啓動流程的分析。由於整個啓動的過程非常長並且代碼非常多,同時受限於筆者的水平,所以本文不會細緻到解釋每一行的代碼的具體作用,只能抽取處關鍵部分的代碼就主體流程進行分析,如有錯誤之處,希望批評指出。

行文脈絡

由於本文會非常長,爲了方便讀者的理解,首先給出筆者的行文脈絡。本文主要沿着:在應用程序1的Activity A內打開另一個應用程序2的Activity B,這一思路進行寫作。流程概括如下:
①Activity A發起一個啓動Activity B的請求(對應主流程分析1~2)
②AMS爲啓動Activity B做準備 (對應主流程分析3~4)
③暫停Activity A(對應主流程分析5~7)
④應用程序1通知AMS完成了暫停操作,AMS處理該消息(對應主流程分析8)
⑤AMS啓動一個新的進程,即應用程序2(對應主流程分析9~11)
⑥在新進程內完成Activity B的創建、啓動操作(對應主流程分析12~13)

時序圖

下面先給出與代碼分析相一致的時序圖,通過該時序圖能更好地理解Activity的啓動流程,讀者可以結合該時序圖與下面的代碼分析一起看。
時序圖

主流程分析

1、Activity#startActivityForResult()方法:
無論從Launcher或者Activity打開一個新的Activity,都會調用startActivity()方法,而這些重載方法最終都會調用startActivityForResult方法,代碼如下:

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

        //把啓動一個Activity的行爲交給Instrumentation處理
        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) {
            mStartedActivity = true;
        }

    } //省略部分代碼..
}

2、Instrumentation#execStartActivity()方法:
在該方法內,主要是通過ActivityManagerService來啓動一個Activity,而該ActivityManagerService是運行在一個獨立的進程空間的,它負責整個Android系統內的所有Activity的創建過程。因此,當前APP進程需要與ActivityManagerService進程進行跨進程通信,這就需要藉助Binder機制了。

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    //省略部分代碼,只看關鍵部分..
    //IApplicationThread有點特殊,它是IBinder對象,用於跨進程通信
    IApplicationThread whoThread = (IApplicationThread) contextThread;

    //ActivityMonitor主要配合InstrumentationTest一起使用,用於統計
    //相匹配的Activity啓動次數,與APP測試有關,這裏省略不談
    if (mActivityMonitors != null) {
        //....
    }

    try {
        //獲取ActivityManagerService代理對象,調用startActivity()方法,
        //這裏實際上通過Binder跨進程調用了ActivityManagerService的方法
        int result = ActivityManager.getService()  //2-1代碼
            .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;
}

2-1、我們看看ActivityManager#getService()代碼做了什麼工作:

public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                //如果進程不同,則獲取一個IActivityManager代理對象
                final IActivityManager am = IActivityManager.Stub.asInterface(b);   
                return am;
            }
        };

顯然,這是一個典型的AIDL使用過程。IActivityManager實際上是一個AIDL文件,編譯器會幫我們把AIDL文件解析成一個Java文件,也即是IActivityManager.java,通過AIDL的方式我們能方便地實現Binder通信。而Binder通信的內部調用過程,這裏不展開來說,我們只關注大體的邏輯即可。上面的IActivityManager.Stub是在編譯器生成的一個內部類,而它的asInterface()方法則是根據當前進程是否與IBinder處於同一進程,如果是,則直接返回IActivityManager的實例,否則會返回一個IActivityManager.Stub.Proxy的代理對象。由於我們的App與AMS肯定不是同一進程,所以這裏獲得的是AMS的遠程代理。(可以參考設計模式中的代理模式)

回到代碼2-1往下看,在獲取了IActivityManager的實例後(實際上是代理對象),會調用它的startActivity(params..)方法,在這個過程中,進行了基於Binder跨進程通信,把一系列的params參數傳遞給AMS,此時AMS的startActivity(params…)被調用了,我們往下看它的代碼。


3、ActivityManagerService#startActivity()
需要注意的是,AMS的代碼在/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 目錄下,這是frameworks層的源碼,在sdk下是看不到的,所以我們需要下載Android的源碼或者在網上查看。(筆者這裏通過Android Frameworks源碼來查看的,有興趣的可以自行前往查看)。

當代碼運行到這裏的時候,我們可以知道以下兩個信息:
①從架構的層面來看,已經從應用層來到了frameworks層。
②從進程的層面來看,當前進程已經是AMS所在的進程。

好了,我們繼續來分析源碼AMS的startActivity()方法的源碼:

@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) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}


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,
        boolean validateIncomingUser) {
    enforceNotIsolatedCaller("startActivity");

    userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

    return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                                                //ActivityStarter內部有一個Request,封裝了請求的具體信息
            .setCaller(caller)                  //設置Caller爲IApplicationThread對象,這個實際上是代理對象
            .setCallingPackage(callingPackage)  //設置包名
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId)
            .execute();

}

可以看到,方法的參數已經包含了一系列啓動Activity所需要的參數,而在最後又調用了ActivityStartController的方法來獲取一個ActivityStarter,並把所有的參數封裝到了ActivityStarter.Request內,最後調用ActivityStarter#execute()方法來啓動一個Activity的創建過程。

3-1、ActivityStartController#obtainStarter()
我們直接從源碼的註釋來看看ActivityStartController有什麼作用:

/**
 * Controller for delegating activity launches.
 *
 * This class' main objective is to take external activity start requests and prepare them into
 * a series of discrete activity launches that can be handled by an {@link ActivityStarter}. It is
 * also responsible for handling logic that happens around an activity launch, but doesn't
 * necessarily influence the activity start. Examples include power hint management, processing
 * through the pending activity list, and recording home activity launches.
 */
public class ActivityStartController {
     //...

    /**
     * @return A starter to configure and execute starting an activity. It is valid until after
     * {@link ActivityStarter#execute} is invoked. At that point, the starter should be
     * considered invalid and no longer modified or used.
     */
    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }
}

從源碼註釋可以知道,它一個是委派Activity啓動的控制器,它管理着一系列的Activity的啓動行爲,並且承擔着Activity啓動過程的電量提示管理、Home的啓動記錄等的工作。但它實際上並不涉及Activity啓動的具體邏輯,它把啓動的邏輯交給了ActivityStarter來處理了。

3-2、ActivityStarter代碼分析

/**
 * Controller for interpreting how and then launching an activity.
 *
 * This class collects all the logic for determining how an intent and flags should be turned into
 * an activity and associated task and stack.
 */
class ActivityStarter {

    //ActivityStartController通過該Factory來獲取一個Starter
    static class DefaultFactory implements Factory {

        //對象池內只有3個活躍對象,也即是ActivityStarter被設計成可循環利用的
        private final int MAX_STARTER_COUNT = 3;        

        private SynchronizedPool<ActivityStarter> mStarterPool =
                new SynchronizedPool<>(MAX_STARTER_COUNT);

        //省略部分代碼...

        @Override
        public ActivityStarter obtain() {
            ActivityStarter starter = mStarterPool.acquire();

            if (starter == null) {
                starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
            }

            return starter;
        }

        @Override
        public void recycle(ActivityStarter starter) {
            starter.reset(true /* clearRequest*/);
            mStarterPool.release(starter);
        }
    }

    //Request類封裝了啓動Activity所需要的一切參數
    private static class Request {
        //省略...
    }

    /**
     * Starts an activity based on the request parameters provided earlier.
     * @return The starter result.
     */
    int execute() {
        try {
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            }else { 
                //... 
            }
        } finally {
            onExecutionComplete();      //最後,會調用ActivityStartController的對應方法,進行Starter的釋放回收
        }
    }

    //省略...
}

ActivityStarter是具體的Activity啓動器,它的內部類Request封裝了啓動Activity的一系列信息,而ActivityStarter被設計成了一個對象池的形式,是可以複用的,因爲Android系統可能會頻繁地啓動Activity,所以啓動器設計出複用的形式可以減少開銷。當execute()被調用的時候,該啓動器便開始執行啓動一個Activity的具體流程,即調用startActivityMayWait(params)方法。

我們順着代碼繼續往下看,即ActivityStarter#startActivityMayWait()

    private 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, SafeActivityOptions options, boolean ignoreTargetSecurity,
            int userId, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {
        
        //由於代碼很長,這裏做了很多刪減,只關注主體部分..

        // Collect information about the target of the Intent.
        //這裏裏面調用了PackageManagerService的方法來解析Intent.
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,0 /* matchFlags */,
            computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));
        //接着將Intent的信息解析爲ActivityInfo
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        synchronized (mService) {
            final ActivityStack stack = mSupervisor.mFocusedStack;
            stack.mConfigWillChange = globalConfig != null
                    && mService.getGlobalConfiguration().diff(globalConfig) != 0;

            final long origId = Binder.clearCallingIdentity(); //設置callingPid和callingUid爲當前進程標識

            final ActivityRecord[] outRecord = new ActivityRecord[1];
            //進一步調用startActivity(params..)方法,24個參數的重載方法
            int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                    allowPendingRemoteAnimationRegistryLookup);

            Binder.restoreCallingIdentity(origId);     //設置callingPid和callingUid爲跨進程調用該方法的進程標識 


            if (outResult != null) {
                outResult.result = res;

                final ActivityRecord r = outRecord[0];

                //根據res來判斷Activity的啓動狀態來做進一步處理
                switch(res) {
                    //Activity正常啓動
                    case START_SUCCESS: {
                        mSupervisor.mWaitingActivityLaunched.add(outResult);
                        do {
                            try {
                                mService.wait();
                            } catch (InterruptedException e) {
                            }
                        } while (outResult.result != START_TASK_TO_FRONT
                                && !outResult.timeout && outResult.who == null);
                        if (outResult.result == START_TASK_TO_FRONT) {
                            res = START_TASK_TO_FRONT;
                        }
                        break;
                    }
                    //Activity並不是真正的啓動,因爲該Intent對應的Activity已在棧頂
                    case START_DELIVERED_TO_TOP: {
                        //省略..

                        break;
                    }
                    //Activity並不是真正的啓動,而是把已有的Activity帶到了前臺
                    case START_TASK_TO_FRONT: {
                        //省略...

                        break;
                    }
                }
            }
            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
            return res;
        }
    }


    /**
     * 經過一系列startActivity()重載方法的調用,最後會調用該方法
     */
    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 {
            mService.mWindowManager.deferSurfaceLayout();   //通知WindowManager暫停佈局

            //進一步調用startActivityUnchecked(params..)方法
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        } finally {
            //如果Activity沒有啓動成功,那麼關閉它,否則可能會出現問題
            final ActivityStack stack = mStartActivity.getStack();
            if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
                stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                        null /* intentResultData */, "startActivity", true /* oomAdj */);
            }
            mService.mWindowManager.continueSurfaceLayout();    //通知WindowManager繼續佈局
        }
        //Activity啓動後還有一些工作要處理
        postStartActivityProcessing(r, result, mTargetStack);

        return result;
    }

    /**
     * 該方法處理了Intent的各種flags以及Activity的啓動模式
     */
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        //初始化信息
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
        //計算LaunchingTaskFlags,對flag進行合法性處理
        computeLaunchingTaskFlags();
        //如果Task已經結束了,要做出處理,然後獲得一個新的Task
        computeSourceStack();

        mIntent.setFlags(mLaunchFlags);

        ActivityRecord reusedActivity = getReusableIntentActivity();    //獲取當前Task的Activity

        //...

        //如果Task內已有Activity,結合即將啓動Activity的launch mode做出處理
        if (reusedActivity != null) {
            //省略具體處理過程暫不作分析,這裏與Activity的啓動模式有關
            //..
        }

        //如果Activity的包名不存在,則啓動失敗
        if (mStartActivity.packageName == null) {
            //省略..

            return START_CLASS_NOT_FOUND;
        }

        //如果即將啓動的Activity與棧頂的Activity相同,那麼判斷是否需要繼續啓動
        final ActivityStack topStack = mSupervisor.mFocusedStack;
        final ActivityRecord topFocused = topStack.getTopActivity();
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        final boolean dontStart = top != null && mStartActivity.resultTo == null
                && top.realActivity.equals(mStartActivity.realActivity)
                && top.userId == mStartActivity.userId
                && top.app != null && top.app.thread != null
                && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
        if (dontStart) {
            //省略...

            return START_DELIVERED_TO_TOP;  //這裏的返回值表示棧頂就是需要啓動的Activity
        }

        //...

        //權限認證
        mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
                mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
        mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
                mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
        
        //...

        //代碼3-3,見下面分析
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);

        //mDoResume爲true,從函數參數傳遞進來的
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                //告訴WindowManager該Activity要做轉場動作了
                mService.mWindowManager.executeAppTransition();
            } else {
                
                //代碼4-1:第一次啓動時,會在這裏進行Activity的啓動
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else if (mStartActivity != null) {
            mSupervisor.mRecentTasks.add(mStartActivity.getTask());
        }

        return START_SUCCESS;
    }

從函數調用棧來看:startActivityMayWait(params..) -> startActivity(params.. ) -> startActivityUnchecked(params..)其中省略了若干個重載方法,這是已經是很深層次的調用棧了,代碼也難以理解,因此我們很難對每行代碼進行詳細的分析也沒有這個必要,我們要善於利用奧卡姆剃刀,抽出主幹部分進行分析即可,我們的關注點在理解Activity的啓動過程及其有關的類的作用,而在此過程有關的Activity launchMode和Flag等可以不做分析。

上面的代碼揭示了,一個Activity如果要啓動,要結合任務棧Task和Activity的啓動模式來進行綜合的處理,比如新建一個棧又或者棧內複用等模式的處理。我們來關注上面標註出來的代碼3-3,看看它內部做了什麼工作。

3-3、ActivityStack#startActivityLocked(params…)

void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
        boolean newTask, boolean keepCurTransition, ActivityOptions options) {
    TaskRecord rTask = r.getTask();
    final int taskId = rTask.taskId;

    //這裏把Activity添加到Stack的頂部
    if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
            // Last activity in task had been removed or ActivityManagerService is reusing task.
            // Insert or replace.
            // Might not even be in.
            insertTaskAtTop(rTask, r);
        }

    TaskRecord task = null;
    if (!newTask) {
        //如果該Task是已存在的,那麼要找到這個Task
        //下面的標誌位用來表示找到的Task是否是前臺Task
        boolean startIt = true;
        //mTaskHistory最後的元素就是最前面的Task
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            task = mTaskHistory.get(taskNdx);
            if (task.getTopActivity() == null) {
                // All activities in task are finishing.
                continue;
            }
            if (task == rTask) {
                //要創建的Activity所在的Task不在前臺
                if (!startIt) {
                    if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
                             + task, new RuntimeException("here").fillInStackTrace());
                    r.createWindowContainer();
                    ActivityOptions.abort(options);
                    return;
                }
                break;
            } else if (task.numFullscreen > 0) {
                startIt = false;
            }
        }
    }
    final TaskRecord activityTask = r.getTask();
    task = activityTask;

    if (!isHomeOrRecentsStack() || numActivities() > 0) {
        
        //如果Activity被設置爲沒有進場動畫效果
        if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
            mWindowManager.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
            mStackSupervisor.mNoAnimActivities.add(r);
        } else {
            //Activity有動畫效果
            int transit = TRANSIT_ACTIVITY_OPEN;
            
            //省略...

            //通知WindowManager來準備轉場效果
            mWindowManager.prepareAppTransition(transit, keepCurTransition);
            mStackSupervisor.mNoAnimActivities.remove(r);
        }
        
        //如果Activity啓動時,它的Task不在前臺,確保該Activity是可見的
        if (r.mLaunchTaskBehind) {
            r.setVisibility(true);
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }

    } 
}

從上面代碼的邏輯可以看出,主要是涉及了窗口的處理,即WindowManager,比如該Activity有沒有進場動畫的標誌位等。因爲啓動一個Activity時,是WindowManager和ActivityManager協同工作的,所以這裏主要邏輯是通過通知窗口管理者來進行Window Container的創建。當然,具體邏輯還是很複雜的,這裏就不再深究了,讓我們回到上一個方法,開始閱讀4-1的代碼。


4-1、ActivityStackSupervisor#resumeFocusedStackTopActivityLocked(params…)
創建一個Activity,並不只是創建一個可視化的視圖而已,它背後任務棧的這一重要的操作,因此打開一個Activity的流程很複雜,其函數的調用棧很深,目前我們來到了ActivityStackSupervisor的地盤,我們來看看這個方法:

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    //省略..

    //如果當前Stack位於前臺
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    //若Stack不在前臺
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || !r.isState(RESUMED)) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.isState(RESUMED)) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }


    return false;
}

邏輯還是很簡單,ActivityStackSupervisor又把打開Activity的任務交給了一個具體的ActivityStack,因爲在之前的代碼中我們把一個即將啓動的Activity放到了這個Stack裏面,現在我們就要對它進行啓動工作,我們繼續往下來看它的代碼。

4-2、ActivityStack#resumeTopActivityUncheckedLocked(params…)

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    //如果當前正在重新啓動一個Activity,那麼跳過
    if (mStackSupervisor.inResumeTopActivity) {
        return false;
    }

    boolean result = false;
    try {
        mStackSupervisor.inResumeTopActivity = true;
        result = resumeTopActivityInnerLocked(prev, options);

        //...
        }
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }

    return result;
}

進一步調用了resumeTopActivityInnerLocked(params..),我們來繼續看這個方法。

4-3、ActivityStack#resumeTopActivityInnerLocked(params…)

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    //下面省略了大量代碼,僅保留主要邏輯

    //從當前棧頂取出正在啓動的Activity
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);

    //...

    // mResumedActivity是當前正在運行的Activity,即處於Resumed狀態的,
    //而next是我們放到了棧頂正在啓動的Activity,注意二者的區別。
    //如果二者相等,那麼不做任何改變
    if (mResumedActivity == next && next.isState(RESUMED)
            && mStackSupervisor.allResumedActivitiesComplete()) {
        //...
        return false;
    }

    //如果屏幕關閉了,沒有Activity需要啓動,並且棧頂的Activity已經暫停,不做改變
    if (shouldSleepOrShutDownActivities()
            && mLastPausedActivity == next
            && mStackSupervisor.allPausedActivitiesComplete()) {
        //...
        return false;
    }

    //...

    //確保該Activity的狀態是正確的,從等待停止隊列移除等
    mStackSupervisor.mStoppingActivities.remove(next);
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);

    //當前有Activity正在執行pause操作,return
    if (!mStackSupervisor.allPausedActivitiesComplete()) {
        //...
        return false;
    }

    //暫停後備堆棧中的所有Activity
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
    if (mResumedActivity != null) {
        //代碼5-1、暫停當前處於Resumed狀態的Activity
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
        
    //與WindowManager交互,確定Activity的啓動動畫
    boolean anim = true;
    if (prev != null) {
        if (prev.finishing) {
            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                    "Prepare close transition: prev=" + prev);
            if (mStackSupervisor.mNoAnimActivities.contains(prev)) {
                anim = false;
                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
            } else {
                mWindowManager.prepareAppTransition(prev.getTask() == next.getTask()
                        ? TRANSIT_ACTIVITY_CLOSE
                        : TRANSIT_TASK_CLOSE, false);
            }
            prev.setVisibility(false);
        }
    } else {
        //...
    }
    mStackSupervisor.mNoAnimActivities.clear();

    ActivityStack lastStack = mStackSupervisor.getLastStack();
    if (next.app != null && next.app.thread != null) {
        //...

    } else {
        //代碼8-4
        //該方法實際上是真正啓動一個Activity的地方,但這裏的調用不會生效
        //因爲,該方法的內部會進行一次判斷:是否有Activity處於未暫停的狀態
        //上面我們跨進程進行了Activity的暫停,在Activity未全部暫停之前,該方法都不會真正被調用。
        //這裏的調用應該是適用於這種情況:別的Activity全部處於暫停狀態,能直接啓動新的Activity了
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    return true;
}

從上面代碼的邏輯來看,主要是先執行5-1的代碼,暫停當前處於Resumed狀態的Activity,然後在最後真正地去啓動當前棧頂就緒的Activity。下面,我們就先來查看怎麼處理暫停Activity的邏輯,接着再看怎麼處理啓動Activity的邏輯。


5-1、ActivityStack#startPausingLocked(params…)

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
        ActivityRecord resuming, boolean pauseImmediately) {
    //省略部分代碼...
    ActivityRecord prev = mResumedActivity;

    if (prev == null) {
        if (resuming == null) {
            Slog.wtf(TAG, "Trying to pause when nothing is resumed");
            mStackSupervisor.resumeFocusedStackTopActivityLocked();
        }
        return false;
    }

    if (prev == resuming) {
        Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
        return false;
    }

    if (prev.app != null && prev.app.thread != null) {
        try {
            //代碼5-2、調用LifecycleManager#scheduleTransaction方法...
            mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                    PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));
        } 
    } 

}

通過mService#getLifecycleManager()獲得了LifecycleManager,這裏的mService就是AMS,而LifecycleManager實際上是類ClientLifecycleManager,它的代碼位於/frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java

5-2、ClientLifecycleManager#scheduleTransaction(params…)

/**
 * Schedule a single lifecycle request or callback to client activity.
 * @param client Target client.
 * @param activityToken Target activity token.
 * @param stateRequest A request to move target activity to a desired lifecycle state.
 * @throws RemoteException
 *
 * @see ClientTransactionItem
 */
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
        @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
    final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
            stateRequest);
    scheduleTransaction(clientTransaction);
}

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();
    }
}

上面的邏輯很清晰,先獲得了一個ClientTransaction對象,然後再調用它的schedule()方法,最後進行了ClientTransaction對象的回收。ClientTransaction封裝了一系列的請求信息,即我們的暫停Activity的所有信息都封裝到了它的內部,同時它實現了Parcelable接口,表示可序列化的,這說明它肯定是用於跨進程傳輸的對象,我們往下看代碼。

5-3、ClientTransaction#schedule()
代碼文件在/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java

    /**
     * Schedule the transaction after it was initialized. It will be send to client and all its
     * individual parts will be applied in the following sequence:
     * 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
     *    that needs to be done before actually scheduling the transaction for callbacks and
     *    lifecycle state request.
     * 2. The transaction message is scheduled.
     * 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
     *    all callbacks and necessary lifecycle transitions.
     */
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

從方法的註釋我們可以知道:
①一次請求會先調用ClientTransaction#preExecute(ClientTransactionHandler)
②然後執行這個請求
③接着調用TransactionExecutor#execute(ClientTransaction)

方法裏面進行了mClient#scheduleTransaction這一調用,這裏的mClient其實就是IApplicationThread,它實際上是一個代理對象,繼承了IBinder,表示我們的APP,主要用於跨進程通信。這裏實際上是一次跨進程調用,此時,從AMS所在的進程切換到了我們的應用進程。


6-1、IApplicationThread#scheduleTransaction(transaction)
IApplicationThread是ActivityThread的一個內部類,我們從那裏尋找它的方法scheduleTransaction(transaction)

public final class ActivityThread extends ClientTransactionHandler {
    //...

    private class ApplicationThread extends IApplicationThread.Stub {
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

        //...
    }
}

可以看到,在該方法的內部進一步調用了ActivityThread#scheduleTransaction()方法,實際上這裏交給了ActivityThread的父類ClientTransactionHandler來處理了。需要注意的是:這裏傳遞過來的ClientTransaction是跨進程通信過程中反序列化生成的對象。

6-2、ClientTransactionHandler#scheduleTransaction(transaction)

public abstract class ClientTransactionHandler {

    // Schedule phase related logic and handlers.

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);  //代碼6-3
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);  //代碼6-4
    }
    //...
}

6-3、ClientTransaction#preExecute(ClientTransactionHandler)
前面5-3有提到過會先調用preExecute方法,這裏得到了印證。我們來看ClientTransactionpreExecute方法。

    public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
        if (mActivityCallbacks != null) {
            final int size = mActivityCallbacks.size();
            for (int i = 0; i < size; ++i) {
                mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
            }
        }
        if (mLifecycleStateRequest != null) {
            mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
        }
    }

這裏主要是進行各種回調的調用,就不繼續展開說了。

6-4、ActivityThread#sendMessage(params…)
繼續執行代碼6-4,這裏調用了sendMessage方法,在ClientTransactionHandler中該方法被標註爲抽象方法,具體實現是在ActivityThread內。實際上,ActivityThread內部的H繼承了Handler,用於處理各種消息。**這也就是主線程的消息循環。**我們直接來看H的代碼:

public final class ActivityThread extends ClientTransactionHandler {
    //...

    class H extends Handler {

        //一系列消息常量的定義..
        public static final int EXECUTE_TRANSACTION = 159;

        public void handleMessage(Message msg) {
            //根據不同的消息類型進行不同的處理
            switch (msg.what) {
                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();
                    }
                    break;
            }
        }

    }
}

這裏把處理的邏輯交由給TransactionExecutor來完成,然後進行ClientTransaction的回收。


7-1、TransactionExecutor#execute(ClientTransaction)
TransactionExecutor可以理解爲一個執行器,專門用於執行各種ClientTransaction

    /**
     * Resolve transaction.
     * First all callbacks will be executed in the order they appear in the list. If a callback
     * requires a certain pre- or post-execution state, the client will be transitioned accordingly.
     * Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
     * either remain in the initial state, or last state needed by a callback.
     */
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }

方法內部首先執行executeCallbacks(transaction),由於對於Pause狀態來說,並沒有添加任何callback,所以我們先省略該方法,接着來看executeLifecycleState(transaction)

7-2、TransactionExecutor#executeLifecycleState(transaction)

/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
    //根據之前的代碼邏輯,這裏的lifecycleItem實際上是PauseLifecycleItem.
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); 
    
    final IBinder token = transaction.getActivityToken();
    final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

    //把ActivityClientRecord的狀態切換到target狀態,這裏是pause,表示把Activity切換到暫停狀態
    cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

    // Execute the final transition with proper parameters.
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}

private void cycleToPath(ActivityClientRecord r, int finish,
        boolean excludeLastState) {
    final int start = r.getLifecycleState();
    //計算從start->finish的狀態變化路徑
    //比如:onCreate->onResume的變化路徑有:onStart、onResume等(不包括初始狀態)
    //該方法很簡單,讀者可以自行去看
    final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
    performLifecycleSequence(r, path);  //把該Activity的狀態沿着這個路徑進行切換
}

/** 該方法把Activity的狀態沿着路徑進行切換 */
private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
    final int size = path.size();
    for (int i = 0, state; i < size; i++) {
        state = path.get(i);
        switch (state) {
            case ON_CREATE:
                mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                        null /* customIntent */);
                break;
            case ON_START:
                mTransactionHandler.handleStartActivity(r, mPendingActions);
                break;
            case ON_RESUME:
                mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                        r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                break;
            case ON_PAUSE:
                mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                        false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                        "LIFECYCLER_PAUSE_ACTIVITY");
                break;
            case ON_STOP:
                mTransactionHandler.handleStopActivity(r.token, false /* show */,
                        0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
                        "LIFECYCLER_STOP_ACTIVITY");
                break;
            case ON_DESTROY:
                mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                        0 /* configChanges */, false /* getNonConfigInstance */,
                        "performLifecycleSequence. cycling to:" + path.get(size - 1));
                break;
            case ON_RESTART:
                mTransactionHandler.performRestartActivity(r.token, false /* start */);
                break;
            default:
                throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
        }
    }
}

上面的代碼邏輯還是很清晰的,主要是先計算出Activity由當前狀態切換到目標狀態所需要走的路徑,然後遍歷這個路徑上的每一個狀態,把Activity依次切換到該狀態,當遍歷到最後一個狀態時,Activity便完成了狀態的切換。上面代碼的最後,又把具體邏輯交給了mTransactionHandler來處理,實際上這裏的mTransactionHandler就是ActivityThread,它繼承了TransactionHandler。因此我們到ActivityThread裏面找相應的方法。

7-3、ActivityThread#handlePauseActivity(params…)
因爲我們的目標狀態是Pause,所以會調用到handlePauseActivity()方法。

@Override
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
        int configChanges, PendingTransactionActions pendingActions, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        if (userLeaving) {
            performUserLeavingActivity(r);
        }

        r.activity.mConfigChangeFlags |= configChanges;
        performPauseActivity(r, finished, reason, pendingActions);

        // Make sure any pending writes are now committed.
        if (r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }
        mSomeActivitiesChanged = true;
    }
}

/**
 * Pause the activity.
 * @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise.
 */
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
        PendingTransactionActions pendingActions) {
    //Honeycomb版本之前的APP在暫停的時候會保存狀態
    final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
    if (shouldSaveState) {
        callActivityOnSaveInstanceState(r);
    }

    performPauseActivityIfNeeded(r, reason);

    // Notify any outstanding on paused listeners
    ArrayList<OnActivityPausedListener> listeners;
    synchronized (mOnPauseListeners) {
        listeners = mOnPauseListeners.remove(r.activity);
    }
    int size = (listeners != null ? listeners.size() : 0);
    for (int i = 0; i < size; i++) {
        listeners.get(i).onPaused(r.activity);
    }

    //省略...

    return shouldSaveState ? r.state : null;
}

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    if (r.paused) {
        // You are already paused silly...
        return;
    }

    try {
        r.activity.mCalled = false;
        mInstrumentation.callActivityOnPause(r.activity);
        
    } catch (Exception e) {
        //省略..
    }
    r.setState(ON_PAUSE);
}

經過層層的調用,我們最後發現調用到了mInstrumentation.callActivityOnPause(r.activity),這個Instrumentation在上面的代碼解析中也有碰到過,我們話不多說直接來看它的實現:

/**
 * Perform calling of an activity's {@link Activity#onPause} method.  The
 * default implementation simply calls through to that method.
 * 
 * @param activity The activity being paused.
 */
public void callActivityOnPause(Activity activity) {
    activity.performPause();
}

到這裏已經很明朗了,已經調用到了Activity#performPause方法,即:

final void performPause() {
    mDoReportFullyDrawn = false;
    mFragments.dispatchPause(); //把暫停事件分發給Fragment,以觸發它們暫停
    mCalled = false;
    onPause();          //調用onPause,這是我們業務邏輯層經常接觸的一個生命週期方法
    writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
    mResumed = false;

    //...
}

到現在,已經觸發了onPause()這個生命週期方法,整個暫停的流程就已經完成了。那麼當一個Activity暫停了,下一步就是執行新Activity的創建流程了。

那麼在client端怎麼通知server端要執行啓動Activity的操作呢?
讓我們把目光定位到代碼7-2的executeLifecycleState(transaction)方法內部,在方法的最後,會依次執行executepostExecute方法,而這裏的lifecycleItem實際上就是PauseActivityItem

7-4、PauseActivityItem#postExecute()

@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    if (mDontReport) {
        return;
    }
    try {
        //通知AMS,Activity已經暫停完畢,是時候啓動Activity了
        ActivityManager.getService().activityPaused(token);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
}

這裏直接通過Binder跨進程通信,告訴AMS該Activity已經暫停了,AMS可以開始啓動原本打算啓動的Activity了。到這一步,APP內的工作暫時完成了,此時進程又會切換到AMS進程內。在開始下一步代碼的閱讀之前,我們需要小結一下代碼6~7客戶端所做的所有工作。

**小結:**APP一直都在進行着主線程的消息循環,等待新的消息的到來。此時,AMS通過Binder跨進程調用了ApplicationThread的某個方法(如上面的scheduleTransaction),該方法運行在客戶端的一條子線程上,然後該方法通過Handler機制,切換到了主線程。此時在主線程執行handleMessage方法,進而調用到具體的某一方法。其中,涉及到Activity生命週期的信息、操作被封裝到了ClientTransaction內部,而具體的每一個生命週期則由ActivityLifecycleItem的子類來表述。在一個操作完成之後(比如上面的pause操作),可能會通知AMS進行下一步操作。然後客戶端繼續進行主線程的消息循環,等待AMS的下一次通知。


8-1、ActivityManagerService#activityPaused(token)
經過客戶端的跨進程調用,AMS的activityPaused(token)被調用了。

    @Override
    public final void activityPaused(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityPausedLocked(token, false);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

根據token來獲取Activity所在的ActivityStack,進一步調用activityPausedLocked(params..)

8-2、ActivityStack#activityPausedLocked(params…)

final void activityPausedLocked(IBinder token, boolean timeout) {
    //先從ActivityStack根據token取出對應的ActivityRecord
    final ActivityRecord r = isInStackLocked(token);
    if (r != null) {
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        //如果二者相等,表示記錄的需要暫停的Activity已經暫停完畢
        if (mPausingActivity == r) {
            mService.mWindowManager.deferSurfaceLayout();
            try {
                completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
            } finally {
                mService.mWindowManager.continueSurfaceLayout();
            }
            return;
        } else {
            //省略...
        }
    }
    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}

這裏沒什麼好說的,我們繼續看completePauseLocked(params..)

8-3、ActivityStack#completePauseLocked(params…)

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
    ActivityRecord prev = mPausingActivity;

    //省略大部分的代碼...

    if (resumeNext) {
        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        if (!topStack.shouldSleepOrShutDownActivities()) {
            mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
        } else {
            //...
        }
    }

}

當代碼執行到這裏的時候,讀者應該對這個方法resumeFocusedStackTopActivityLocked(params..)有點眼熟吧?上面已經執行過該方法了,接下來的調用鏈都是一樣的了,最終會執行到ActivityStackSupervisor#startSpecificActivityLocked(params..)這個方法,進行Activity的真正啓動過程。

8-4、ActivityStackSupervisor#startSpecificActivityLocked(params…)

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    //獲取Activity所對應的進程記錄
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    getLaunchTimeTracker().setLaunchTime(r);

    //如果該進程已經啓動了,那麼直接開始啓動Activity
    if (app != null && app.thread != null) {
        try {
            //若該Activity的flag不包含多進程標誌位 或 不是安卓框架的組件
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                // Don't add this if it is a platform component that is marked
                // to run in multiple processes, because this is actually
                // part of the framework so doesn't make sense to track as a
                // separate apk in the process.
                // 如果它是一個標記爲多進程運行的平臺組件,則不要添加該項,
                // 因爲這實際上是安卓框架的一部分,因此在進程中作爲單獨的apk進行跟蹤是沒有意義的。
                app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                        mService.mProcessStats);
            }
            //真正地啓動一個Activity
            realStartActivityLocked(r, app, andResume, checkConfig);    
            return;
        } catch (RemoteException e) {
            //...
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
    }

    //代碼9-1:否則,先啓動一個新的進程,然後再啓動Activity
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

代碼的邏輯很清晰明瞭,主要是先判斷Activity所對應的進程是否已經存在,如果存在了那就直接去執行真正的啓動Activity過程;如果該進程還不存在,那麼就要去啓動一個進程。接下來的分析有兩條路可以走,一是沿着Activity啓動進行分析;二是沿着進程的啓動進行分析。實際上進程的啓動完畢之後也還是要進行Activity的啓動的。也就是說調用了mService.startProcessLocked(params)後,會啓動新的進程,然後ActivityStackSupervisor再次調用realStartActivityLocked(params..)在進程內啓動Activity。
其實,這個調用順序符合這一種情況:在進程A的ActivityA內啓動了進程B的ActivityB,此時先暫停進程A的ActivityA,然後進程B還沒有啓動,那麼先啓動進程B,然後再啓動ActivityB。
因此,接下來我們先來看怎樣啓動一個新的進程。


9-1、ActivityManagerService#startProcessLocked(params…)

final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        String hostingType, ComponentName hostingName, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}

private final boolean startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
        //省略大部分代碼...

        final String entryPoint = "android.app.ActivityThread";
        return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
                runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                startTime);
    } 
}
//一系列startProcessLocked(params..)重載方法的調用
//最終會調用下面的startProcess(params..)方法

private ProcessStartResult startProcess(String hostingType, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    try {
        final ProcessStartResult startResult;
        if (hostingType.equals("webview_service")) {
            startResult = startWebView(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, null,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        } else {
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        }
        return startResult;
    } 
}

中間省略了大部分的重載方法的調用,最後來到了Process.start(params..),把一系列進程有關的信息都傳遞了進去,根據這些信息來創建一個進程。

9-2、Process#start(params…)
這個類的源碼在Android SDK內可以找到,我們直接看它的代碼:

public static final ProcessStartResult start(final String processClass,
                              final String niceName,
                              int uid, int gid, int[] gids,
                              int runtimeFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String invokeWith,
                              String[] zygoteArgs) {
    return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}

這裏我們需要關注一個參數processClass,當一個進程被啓動後,以processClass爲類名的類的main(args)函數會被調用。而這裏的processClass是代碼9-1中傳遞進來的“android.app.ActivityThread”。那麼也就是說,一個新的進程啓動後,它的ActivityThread的main()函數會最先得到執行。所以,ActivityThread#main()是整個應用程序的入口

9-3、zygoteProcess#start(params…)
代碼執行到了zygoteProcess的start(params…)方法,我們先來看一下代碼的執行:

public final Process.ProcessStartResult start(final String processClass,
        final String niceName,int uid, int gid, int[] gids,
        int runtimeFlags, int mountExternal,int targetSdkVersion,
        String seInfo,String abi,String instructionSet,String appDataDir,
        String invokeWith,String[] zygoteArgs) {
    try {
        return startViaZygote(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
                zygoteArgs);
    } catch{
        //...
    }
}

private Process.ProcessStartResult startViaZygote(params...)throws ZygoteStartFailedEx {
    ArrayList<String> argsForZygote = new ArrayList<String>();

    //爲zygote進程添加各種參數...
    argsForZygote.add("--runtime-args");
    argsForZygote.add("--setuid=" + uid);
    argsForZygote.add("--setgid=" + gid);
    //省略...

    //這裏加了鎖,同一時間內只允許一條線程執行創建進程的操作
    synchronized(mLock) {
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
}

/**
 * 把新進程的參數發給zygote進程,它會創建一個子進程,並返回子進程的pid
 *
 */
@GuardedBy("mLock")
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, ArrayList<String> args)
        throws ZygoteStartFailedEx {
    try {
        //這裏的跨進程通信,使用的是socket通信機制
        //由於這裏都是在鎖的機制下執行,所以不會出現併發錯誤  
        final BufferedWriter writer = zygoteState.writer;
        final DataInputStream inputStream = zygoteState.inputStream;

        //把所有新進程的參數都寫入緩衝區
        writer.write(Integer.toString(args.size()));
        writer.newLine();

        for (int i = 0; i < sz; i++) {
            String arg = args.get(i);
            writer.write(arg);
            writer.newLine();
        }

        writer.flush();

        // Should there be a timeout on this?
        Process.ProcessStartResult result = new Process.ProcessStartResult();

        //讀取zygote進程返回的值,這就是新進程的pid
        result.pid = inputStream.readInt();
        result.usingWrapper = inputStream.readBoolean();

        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }
        return result;
    } 
}

zygote到底是何方神聖呢?其實在安卓系統啓動的過程中,zygote進程就會被啓動,它負責了整個frameworks層和application層的所有進程的創建和啓動工作。也就是說,所有的進程都是它孕育出來的,都是它的子進程。同時,zygote的中文意思受精卵剛好與它的行爲相符合。
需要注意的是,上面的代碼都是運行在AMS內,只不過最後通過socket跨進程通信的方式通知了zygote進程來fork一個子進程,並且獲取到了子進程的pid。該子進程創建、啓動完畢之後,ActivityThread#main()方法就得到了調用。


10-1、ActivityThread#main()
ActivityThread的main()方法可以說是我們應用程序的開端,它運行在一個新的進程空間內。當一個新的進程啓動完畢開始運行後,它首先要做的是通知AMS它被啓動了,因爲此時AMS還等着它去執行啓動Activity的後續流程呢。我們來看看main()方法做了什麼工作:

public static void main(String[] args) {
    //初始化環境
    Environment.initForCurrentUser();

    // Set the reporter for event logging in libcore
    EventLogger.setReporter(new EventLoggingReporter());

    // 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
    Looper.prepareMainLooper();

    //從命令行參數中獲取序列號
    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的實例
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);    //通知AMS進行綁定操作

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

    Looper.loop();      //開啓主線程的消息循環

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

代碼的邏輯很清晰,關鍵的地方上面也有註釋。可以看出,在main()函數的最後,開啓了主線程的消息循環,通過Handler和Looper的組合,可以不斷地處理AMS、WMS發過來的消息請求等,有關主線程消息循環的內容,有興趣的可以自行查閱相關的信息,這裏不做展開講述。我們的關注點放在thread.attach(false,startSeq)這行代碼內,我們看看它做了什麼工作吧。

10-2、ActivityThread#attach(params…)

private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        //獲取AMS在客戶端的代理對象
        final IActivityManager mgr = ActivityManager.getService();
        try {
            //進行跨進程通信,通知AMS進行綁定操作
            //這裏的mAppThread就是ApplicationThread,在ActivityThread
            //被實例化的時候,它也被實例化了。
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        
    } else {
        //...
    }
    //...
}

上面的代碼出現了ApplicationThread對象,它在前面已經出現過很多次了,它是一個Binder對象,用於AMS來跨進程與APP進行消息通信。這裏通過Binder跨進程通信,調用了AMS的attachApplication(params…)方法。我們再次打開AMS的代碼,找到該方法。(需要注意的是:應用程序的主線程執行完該方法之後,繼續進行消息循環,以等待下一次AMS的消息。)

10-3、ActivityManagerService#attachApplication(params…)

@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
    synchronized (this) {
        //..
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
    }
}

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
    ProcessRecord app;
    long startTime = SystemClock.uptimeMillis();
    //根據pid來獲取進程記錄
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            app = mPidsSelfLocked.get(pid);
        }
    } else {
        app = null;
    }

    //ProcessRecord保存了當前的IApplicationThread,即保存了客戶端的一個代理對象
    //AMS能根據該Binder對象快速找到所指的應用
    app.makeActive(thread, mProcessStats);  
    
    //省略大部分代碼...

        if (app.isolatedEntryPoint != null) {
            //...
        } else if (app.instr != null) {
            //代碼11-1、跨進程調用ApplicationThread的方法,告訴APP端有關該進程的信息
            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);
            } else {
                //...
            }
            
        } 

    // See if the top visible activity is waiting to run in this process...
    if (normalMode) {
        try {
            //代碼12-1、告訴ActivityStackSupervisor,該app已經完成了綁定操作,可以啓動一個Activity了
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } 
    }
    return true;
}

上面已經省略了大部分的代碼,很多都是異常狀態的處理以及初始化等邏輯,核心在於thread.bindApplication(params..)mStackSupervisor.attachApplicationLocked(app)這兩個方法的調用上。前一行代碼通過IApplicationThread跨進程通信,調用了APP端的相應方法,把有關進程的重要信息傳遞了過去。這樣便完成從客戶端到服務端的綁定操作。後一行代碼,通過ActivityStackSupervisor來找到對應的ActivityStack,然後進行綁定,這樣便完成了從服務端到客戶端的綁定操作。通過這兩個操作,客戶端的應用程序知道了自己的應用信息、進程信息等;而服務端則知道了客戶端的Binder代理對象,方便之後的跨進程操作。


11-1、ApplicationThread#bindApplication(params…)
我們先來看該方法的調用,我們又從AMS進程回到了應用進程:

public final void bindApplication(params..) {

    if (services != null) {

        // Setup the service cache in the ServiceManager
        ServiceManager.initServiceCache(services);
    }

    setCoreSettings(coreSettings);

    AppBindData data = new AppBindData();
    data.processName = processName;
    data.appInfo = appInfo;
    data.providers = providers;
    //省略賦值代碼..
        
    //通過Handler發送消息
    sendMessage(H.BIND_APPLICATION, data);
}

由此可見,App的有關信息從AMS傳遞了過來,並保存在了AppBindData這個對象內。接着,就是我們熟悉的發送消息過程,通過Handler切換到主線程,在主線程內處理這個消息。代碼如下:

public void handleMessage(Message msg) {
    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;        
    }
    Object obj = msg.obj;
    if (obj instanceof SomeArgs) {
        ((SomeArgs) obj).recycle();
    }
}

得益於主線程的消息循環,當H接受到BIND_APPLICATION的消息時,就能馬上開始處理這個消息,處理完畢後繼續消息循環。

11-2、ActivityThread#handleBindApplication(data)

private void handleBindApplication(AppBindData data) {
    //省略大部分代碼...

    //創建上下文環境context
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        
    Application app;
    try {
        app = data.info.makeApplication(data.restrictedBackupMode, null);
        
        //....
        try {
            mInstrumentation.callApplicationOnCreate(app);
        }
    }
}

以上省略了絕大部分的代碼,很多都是初始化代碼,比如加載各種庫等。當Application初始化完畢之後,調用了mInstrumentation.callApplicationOnCreate(app)

11-3、Instrumentation#callApplicationOnCreate(app)

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

很簡單,調用了Application#onCreate()方法,也就是我們業務層常重寫的方法之一,代碼執行到這裏,應用程序的初始化已經完成了。下面就是在應用程序的基礎上啓動一個Activity了。


12-1、ActivityStackSupervisor#attachApplicationLocked(app)
回到10-3的代碼,繼續往下執行,接着AMS就會調用mStackSupervisor.attachApplicationLocked(app)方法,可想而知,在方法的內部,應該是要啓動一個Activity了。因爲一切的準備工作都已經完成了。

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    for (...) {
        for (...) {
            for (int i = 0; i < size; i++) {
                final ActivityRecord activity = mTmpActivityList.get(i);

                //如果該ActivityRecord的進程字段爲空 並且進程uid與Activity的進程id相同
                //並且 進程名字與Activity的進程名字相同
                if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                        && processName.equals(activity.processName)) {
                    try {
                        //啓動該Activity
                        if (realStartActivityLocked(activity, app,
                                top == activity /* andResume */, true /* checkConfig */)) {
                            didSomething = true;
                        }
                    } 
                }
            }
        }
    }
    return didSomething;
}

上面代碼的邏輯主要是遍歷所有的任務棧,找到活躍的任務棧後,再在其中找到需要啓動的Activity,將它啓動。啓動的邏輯放在了realStartActivityLocked(params..),終於,我們又看到了這個方法,殊途同歸。

12-2、ActivityStackSupervisor#realStartActivityLocked(params…)

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {

    //這裏進行了判斷,如果有Activity處於未暫停的狀態,則不能啓動一個新的Activity
    //由於我們是從客戶端通知server來啓動一個Activity的,因此已經不存在未暫停的Activity了
    if (!allPausedActivitiesComplete()) {   
        return false;
    }

    final TaskRecord task = r.getTask();
    final ActivityStack stack = task.getStack();

    try {
            //創建一個客戶端的事務
            final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                    r.appToken);
            //添加callback,留意這裏的添加了LaunchActivityItem
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                    profilerInfo));

            //爲該事務的目標設置爲ResumeActivityItem,即啓動一個Activity,並改變它
            //的生命週期到Resumed狀態
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
            } 
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

            //通過事務管理器執行一個事務
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        } 
    return true;
}

可以看到,我們再次遇到了熟悉的ClientTransaction,前面解析暫停Activity時也遇到它,那麼接下來的邏輯應該就是與暫停的邏輯差不多了,只不過現在的ActivityLifecycleItem變成了ResumeActivityItem,即Activity的目標狀態是resumed。接下來的調用鏈與前面見過的是一致的,即:ClientLifecycleManager#scheduleTransaction(clientTransaction)
——>ClientTransaction.schedule()
——>IApplicationThread.scheduleTransaction(this)
——>ActivityThread#scheduleTransaction(transaction)
——>H#handleMessage(msg)
——>TransactionExecutor#execute(transaction)
其中,通過IApplicationThread這個Binder對象進行了跨進程調用,調用了APP端的方法,此時從AMS進程切換到了我們的應用進程。緊接着,通過Handler機制切換到了主線程,並在主線程處理EXECUTE_TRANSACTION這個消息,接着進一步交給TransactionExecutor來處理這個事務。


13-1、TransactionExecutor#execute(transaction)
在代碼7-1已經介紹過這個方法了,我們再來簡單看一下就行:

    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }

在代碼12-2中,我們有留意到初始化clientTransaction時,爲它添加了一個callback,即LaunchActivityItem,那麼這裏首先會執行executeCallbacks(transaction)方法。

13-2、TransactionExecutor#executeCallbacks(transaction)

public void executeCallbacks(ClientTransaction transaction) {
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    if (callbacks == null) {
        // No callbacks to execute, return early.
        return;
    }
    log("Resolving callbacks");

    final IBinder token = transaction.getActivityToken();
    ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

    //根據前面的代碼,這裏的size爲1
    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
        final ClientTransactionItem item = callbacks.get(i);
        log("Resolving callback: " + item);

        //這裏的Item實際上就是LaunchActivityItem.
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);

        //...
    }
}

在方法內部調用了LaunchActivityItem的相關方法,其中關鍵是LaunchActivityItem#execute(params..)

13-3、LaunchActivityItem#execute(params…)

public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
    //實例化一個ActivityClientRecord
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client);
    //實際上調用的是ActivityThread的handleLaunchActivity方法
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

這裏的ClientTransactionHandlerActivityThread的父類,而ActivityThread重寫了該方法,因此我們到ActivityThread尋找該方法。

13-4、ActivityThread#handleLaunchActivity(params…)

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

    final Activity a = performLaunchActivity(r, customIntent);

    //...

    return a;
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
    //省略部分代碼..

    ActivityInfo aInfo = r.activityInfo;
    ContextImpl appContext = createBaseContextForActivity(r);   //創建Context
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);    //創建一個新的Activity
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } 

    try {
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (activity != null) {
            appContext.setOuterContext(activity);
            //activity綁定application
            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 (r.isPersistable()) {
                //前面創建了Activity,接下來觸發它的生命週期方法
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }

            r.activity = activity;
        }
        r.setState(ON_CREATE);  //設置Activity此時的狀態爲onCreate

        mActivities.put(r.token, r);

    return activity;
}

經過一系列的創建、初始化過程,終於到了Instrumentation#callActivityOnCreate(params..),顯然,這裏就是觸發Activity生命週期方法的地方了。

13-5、Instrumentation#callActivityOnCreate(params…)

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

沒什麼好說的,下一步就是Activity#performCreate(bundle)

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

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    mCanEnterPictureInPicture = true;
    restoreHasCurrentPermissionRequest(icicle);
    if (persistentState != null) {
        onCreate(icicle, persistentState);  
    } else {
        onCreate(icicle);   //onCreate()生命週期方法調用
    }
    writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
    mActivityTransitionState.readState(icicle);

    mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
            com.android.internal.R.styleable.Window_windowNoDisplay, false);
    mFragments.dispatchActivityCreated();   //告訴Fragment分發create事件
    mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
}

最後,終於來到了Activity#onCreate()方法,也這就是我們應用Activity默認重寫的一個方法。到了這一步,一個Activity終於真正地創建、啓動成功了。但還沒有完成,因爲我們的目標狀態是resumed,所以我們還要把Activity的狀態逐步切換到onResume狀態。
讓我們回到代碼13-1的executeLifecycleState(transaction),這個方法讀者應該也是熟悉的了,因爲在處理pause狀態時也曾經遇到過了。那麼接下來的邏輯就顯而易見了,具體的邏輯就在代碼7-2處,只不過現在的狀態路徑變成了:onStart和onResume,也就是會分別調用ActivityThread#handleStartActivityActivityThread#handleResumeActivity;接着進一步調用到Activity#performStart()Activity#performResume()。最後,我們熟悉的生命週期方法onStart()onResume()都會得到調用。

本文到這裏就告一段落了,整篇文章很長,爲耐心看到這裏的你點贊~希望這篇文章能對您有所裨益,謝謝閱讀!

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