Android源碼探究:Activity啟動流程完全解析(上)

概述

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

行文脈絡

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

限于文章的篇幅,本文只介紹①~③,剩下的內容會在下一篇文章給出。

時序圖

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


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系統(tǒng)內的所有Activity的創(chuàng)建過程。因此,當前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一起使用,用于統(tǒng)計
    //相匹配的Activity啟動次數(shù),與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的方式我們能方便地實現(xiàn)Binder通信。而Binder通信的內部調用過程,這里不展開來說,我們只關注大體的邏輯即可。上面的IActivityManager.Stub是在編譯器生成的一個內部類,而它的asInterface()方法則是根據(jù)當前進程是否與IBinder處于同一進程,如果是,則直接返回IActivityManager的實例,否則會返回一個IActivityManager.Stub.Proxy的代理對象。由于我們的App與AMS肯定不是同一進程,所以這里獲得的是AMS的遠程代理。(可以參考設計模式中的代理模式)

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


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

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

好了,我們繼續(xù)來分析源碼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();

}

可以看到,方法的參數(shù)已經(jīng)包含了一系列啟動Activity所需要的參數(shù),而在最后又調用了ActivityStartController的方法來獲取一個ActivityStarter,并把所有的參數(shù)封裝到了ActivityStarter.Request內,最后調用ActivityStarter#execute()方法來啟動一個Activity的創(chuàng)建過程。

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被設計成可循環(huán)利用的
        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所需要的一切參數(shù)
    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系統(tǒng)可能會頻繁地啟動Activity,所以啟動器設計出復用的形式可以減少開銷。當execute()被調用的時候,該啟動器便開始執(zhí)行啟動一個Activity的具體流程,即調用startActivityMayWait(params)方法。

我們順著代碼繼續(xù)往下看,即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個參數(shù)的重載方法
            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];

                //根據(jù)res來判斷Activity的啟動狀態(tài)來做進一步處理
                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;
        }
    }


    /**
     * 經(jīng)過一系列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沒有啟動成功,那么關閉它,否則可能會出現(xiàn)問題
            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繼續(xù)布局
        }
        //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已經(jīng)結束了,要做出處理,然后獲得一個新的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與棧頂?shù)腁ctivity相同,那么判斷是否需要繼續(xù)啟動
        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,從函數(shù)參數(shù)傳遞進來的
        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;
    }

從函數(shù)調用棧來看:startActivityMayWait(params..) -> startActivity(params.. ) -> startActivityUnchecked(params..)其中省略了若干個重載方法,這是已經(jīng)是很深層次的調用棧了,代碼也難以理解,因此我們很難對每行代碼進行詳細的分析也沒有這個必要,我們要善于利用奧卡姆剃刀,抽出主干部分進行分析即可,我們的關注點在理解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) {
                //要創(chuàng)建的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協(xié)同工作的,所以這里主要邏輯是通過通知窗口管理者來進行Window Container的創(chuàng)建。當然,具體邏輯還是很復雜的,這里就不再深究了,讓我們回到上一個方法,開始閱讀4-1的代碼。


4-1、ActivityStackSupervisor#resumeFocusedStackTopActivityLocked(params...)
創(chuàng)建一個Activity,并不只是創(chuàng)建一個可視化的視圖而已,它背后任務棧的這一重要的操作,因此打開一個Activity的流程很復雜,其函數(shù)的調用棧很深,目前我們來到了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里面,現(xiàn)在我們就要對它進行啟動工作,我們繼續(xù)往下來看它的代碼。

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..),我們來繼續(xù)看這個方法。

4-3、ActivityStack#resumeTopActivityInnerLocked(params..)

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

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

    //...

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

    //如果屏幕關閉了,沒有Activity需要啟動,并且棧頂?shù)腁ctivity已經(jīng)暫停,不做改變
    if (shouldSleepOrShutDownActivities()
            && mLastPausedActivity == next
            && mStackSupervisor.allPausedActivitiesComplete()) {
        //...
        return false;
    }

    //...

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

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

    //暫停后備堆棧中的所有Activity
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
    if (mResumedActivity != null) {
        //代碼5-1、暫停當前處于Resumed狀態(tài)的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處于未暫停的狀態(tài)
        //上面我們跨進程進行了Activity的暫停,在Activity未全部暫停之前,該方法都不會真正被調用。
        //這里的調用應該是適用于這種情況:別的Activity全部處于暫停狀態(tài),能直接啟動新的Activity了
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    return true;
}

從上面代碼的邏輯來看,主要是先執(zhí)行5-1的代碼,暫停當前處于Resumed狀態(tài)的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的所有信息都封裝到了它的內部,同時它實現(xiàn)了Parcelable接口,表示可序列化的,這說明它肯定是用于跨進程傳輸?shù)膶ο螅覀兺驴创a。

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)
②然后執(zhí)行這個請求
③接著調用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);
        }
    }

這里主要是進行各種回調的調用,就不繼續(xù)展開說了。

6-4、ActivityThread#sendMessage(params..)
繼續(xù)執(zhí)行代碼6-4,這里調用了sendMessage方法,在ClientTransactionHandler中該方法被標注為抽象方法,具體實現(xiàn)是在ActivityThread內。實際上,ActivityThread內部的H繼承了Handler,用于處理各種消息。這也就是主線程的消息循環(huán)。我們直接來看H的代碼:

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

    class H extends Handler {

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

        public void handleMessage(Message msg) {
            //根據(jù)不同的消息類型進行不同的處理
            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可以理解為一個執(zhí)行器,專門用于執(zhí)行各種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");
    }

方法內部首先執(zhí)行executeCallbacks(transaction),由于對于Pause狀態(tài)來說,并沒有添加任何callback,所以我們先省略該方法,接著來看executeLifecycleState(transaction)。

7-2、TransactionExecutor#executeLifecycleState(transaction)

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

    //把ActivityClientRecord的狀態(tài)切換到target狀態(tài),這里是pause,表示把Activity切換到暫停狀態(tài)
    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的狀態(tài)變化路徑
    //比如:onCreate->onResume的變化路徑有:onStart、onResume等(不包括初始狀態(tài))
    //該方法很簡單,讀者可以自行去看
    final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
    performLifecycleSequence(r, path);  //把該Activity的狀態(tài)沿著這個路徑進行切換
}

/** 該方法把Activity的狀態(tài)沿著路徑進行切換 */
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由當前狀態(tài)切換到目標狀態(tài)所需要走的路徑,然后遍歷這個路徑上的每一個狀態(tài),把Activity依次切換到該狀態(tài),當遍歷到最后一個狀態(tài)時,Activity便完成了狀態(tài)的切換。上面代碼的最后,又把具體邏輯交給了mTransactionHandler來處理,實際上這里的mTransactionHandler就是ActivityThread,它繼承了TransactionHandler。因此我們到ActivityThread里面找相應的方法。

7-3、ActivityThread#handlePauseActivity(params..)
因為我們的目標狀態(tài)是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在暫停的時候會保存狀態(tài)
    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);
}

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

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

到這里已經(jīng)很明朗了,已經(jīng)調用到了Activity#performPause方法,即:

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

    //...
}

到現(xiàn)在,已經(jīng)觸發(fā)了onPause()這個生命周期方法,整個暫停的流程就已經(jīng)完成了。那么當一個Activity暫停了,下一步就是執(zhí)行新Activity的創(chuàng)建流程了。

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

7-4、PauseActivityItem#postExecute()

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

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

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

更多閱讀
Android源碼探究:Activity啟動流程完全解析(下)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容