Android -- Activity啓動流程分析

Android -- Activity啓動流程分析


Activity是Apk向用戶提供交互界面的接口,它應該是我們平時最常見、最常用的組件了。在Android系統中,Activity以任務棧的形式管理,這部分內容可以參考之前的Activity任務棧部分。本文我們側重分析Activity啓動的流程,來了解Activity啓動過程中,系統到底做了哪些處理。


Activity的啓動過程是比較複雜的,涉及到的代碼量之大,調用關係之複雜,都是令人絕望的。不過,我們並不需要讀懂這個過程中的所有代碼,這是沒必要、也不現實的。我們的目的是掌握Activity啓動過程中一些重要函數調用的含義,掌握Activity啓動實現的機制,並理解Activity生命週期函數的調用時機;有了這些基礎,如果我們再有興趣繼續深入分析,就不會那麼絕望了。


我們有兩種方式啓動一個Activity,一是在Launcher中點擊應用的圖標;二是在應用內部,通過函數調用啓動Activity;這裏我們先介紹第一種情況,後續再介紹第二種情況。系統啓動的第一個Apk是Launcher,我們正是從Launcher中點擊某個Apk的icon,並進入該應用的。假設我們有一個名叫Test的Apk,它具有如下的配置清單文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.coder.lovebugs">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".HomeActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
		
        <activity android:name=".SecondActivity" />


    </application>

</manifest>
我們以此Apk爲例,簡要分析從Launcher啓動該Apk、並最終將HomeActivity顯示給用戶的流程。


當我們點擊Launcher上應用的圖標時,會調用Launcher::startActivitySafely(View v, Intent intent, Object tag) 函數來開始啓動應用:

    boolean startActivitySafely(View v, Intent intent, Object tag) {
        boolean success = false;
        try {
            success = startActivity(v, intent, tag);//層次調用startActivity(View v, Intent intent, Object tag)
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
        }
        return success;
    }
根據函數調用,下一步層次調用:
    boolean startActivity(View v, Intent intent, Object tag) {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//默認添加了FLAG_ACTIVITY_NEW_TASK啓動標誌位

        try {
             ...
            if (useLaunchAnimation) {
               ...
            } else {
                if (user == null || user.equals(android.os.Process.myUserHandle())) {
                    startActivity(intent);//層次調用,Activity::startActivity(Intent)方法
                } else {
                   ...
                }
            }
            return true;
        } catch (SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Launcher does not have the permission to launch " + intent +
                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +
                    "or use the exported attribute for this activity. "
                    + "tag="+ tag + " intent=" + intent, e);
        }
        return false;
    }
因爲,一個應用啓動時,系統都會爲它創建一個單獨的任務棧,所以這裏添加了Intent.FLAG_ACTIVITY_NEW_TASK標誌,用來告知系統需要爲這個應用創建一個單獨的任務棧。隨後繼續層次調用,調用父類Activity::startActivity(Intent)函數去啓動應用:
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {//Bundle爲空
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

參數intent包含了我們需要啓動的Activity的一些信息,如下:

	action: android.intent.action.MAIN //表明是主Activity
	category: android.intent.category.LAUNCHER //表明需要在Launcher上顯示圖標
	component:com.coder.lovebugs.HomeActivity //需要啓動的Activity組件名稱
由於options參數爲null,則繼續分析:
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);//調用Instrumentation的方法;注意參數信息;mToken等參數都標識了Launcher組建的信息
            ...
        } else {
            ...
        }
    }

參數requestCode爲-1,表明該Activity退出時不需要返回結果給Launcher。對象mInstrumentation是Instrumentation類型;Instrumentation負責監控組件與系統之間的交互過程,Activity、Service等都通過它來與系統交互;進入Instrumentation處理之後,Activity組件的啓動過程就會交給ActivityManagerService(AMS)了,爲了後續流程的分析,我們先明確下此處各個傳參的基本含義:


  • this:Activity實際是Context的子類,它代表了當前啓動該Activity的組件,即Launcher
  • mMainThread.getApplicationThread():mMainThread是ActivityThread類型,它代表了Launcher應用的主線程;getApplicationThread()函數返回的其實是ApplicationThread類型(實現了IApplicationThread接口),它是一個Binder子類;AMS通過該對象,就可以在Activity組件啓動過程與Launcher的主線程進行交互了
  • mToken:在AMS中,每個Activity組件都對應一個ActivityRecord對象,AMS以ActivityRecord類型來管理Activity組件。AMS爲了將自己內部管理的ActivityRecord實例與某個Activity組件對應起來,就使用了一個IBinder實例來作爲橋樑,對Activity和ActivityRecord進行關聯。所以,AMS通過傳入的Activity::mToken對象就可以在它內部找到這個Activity對應的ActivityRecord實例了
  • this:也是代表當前啓動該Activity的組件,即Launcher
  • intent:它描述了我們需要啓動的Activity組件的參數


接着進入Instrumentation.execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options):

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;//Launcher組件的主線程
        ...
       
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);//即將離開的進程是Launcher進程
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);//進入ActivityManagerService::startActivity()方法
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

該函數中,我們的Activity啓動流程就即將進入AMS了;AMS是系統核心服務,四大組件的生命週期過程都與AMS息息相關。首先將傳入的表示Launcher進程主線程的contextThread轉換成IApplicationThread類型,然後按參數調用AMS::startActivity()函數。


AMS是Binder體系的一個實現類,它的繼承結構圖如下所示:



依據Binder IPC機制,我們首先進入ActivityManagerProxy中查看:

public int ActivityManagerProxy::startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeString(callingPackage);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }

發送了START_ACTIVITY_TRANSACTION類型的請求,再直接進入AMS的Server端看該類型請求的處理:

public boolean ActivityManagerNative::onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case START_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            IBinder resultTo = data.readStrongBinder();
            String resultWho = data.readString();
            int requestCode = data.readInt();
            int startFlags = data.readInt();
            ProfilerInfo profilerInfo = data.readInt() != 0
                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
            Bundle options = data.readInt() != 0
                    ? Bundle.CREATOR.createFromParcel(data) : null;
            int result = startActivity(app, callingPackage, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }
...
}
這裏直接調用Server端實現AMS中的同簽名的startActivity()函數,處理這次請求調用;這樣我們的Activity啓動工作就正式進入了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) {
            //caller是指向Launcher的ApplicationThread對象,AMS可以通過該對象與Launcher的主線程進行交互
            //intent包含了所要啓動的Activity的信息
            //resultTo是一個ActivityRecord的IBidner對象,它在AMS中會對應Launcher中的一個Activity組件
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());//層次調用
    }
層次調用AMS::startActivityAsUser():
    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null/*inTask參數爲null*/);//ActivityStarter實例用於管理如何啓動Activity
    }
繼而調用ActivityStarter::startActivity()。AMS在處理Activity啓動過程中,引入了很多的輔助類型;其中,需要注意的幾個類型關係如下圖所示


ActivityStarter是AMS管理Activity啓動過程的一個管理類,直接看它的函數調用:

final int ActivityStarter::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, IActivityManager.WaitResult outResult, Configuration config,
            Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask) {
        // Refuse possible leaked file descriptors
        if (intent != null && intent.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        ...
        // Save a copy in case ephemeral needs it
        final Intent ephemeralIntent = new Intent(intent);
        // Don't modify the client's object!
        intent = new Intent(intent);

        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);//通過PMS根據該intent獲取到需要啓動的組件的更多信息
        if (rInfo == null) {//這種場景下,系統得到的rInfo不會爲null
            ...
        }
        // Collect information about the target of the Intent.
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);//將獲取到的Activity組件信息保存到ActivityInfo對象中

        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
        ActivityStackSupervisor.ActivityContainer container =
                (ActivityStackSupervisor.ActivityContainer)iContainer;
        synchronized (mService) {
            if (container != null && container.mParentActivity != null &&
                    container.mParentActivity.state != RESUMED) {
                // Cannot start a child activity if the parent is not resumed.
                return ActivityManager.START_CANCELED;
            }
            final int realCallingPid = Binder.getCallingPid();
            final int realCallingUid = Binder.getCallingUid();
            int callingPid;
            if (callingUid >= 0) {
                callingPid = -1;
            } else if (caller == null) {
                callingPid = realCallingPid;
                callingUid = realCallingUid;
            } else {
                callingPid = callingUid = -1;
            }
            ...
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask);//繼續處理Activity組件啓動流程

            ...
    }
}
首先通過resolveIntent()/resolveActivity()調用,從PackageManagerService中獲取到當前需要啓動的Activity的一些信息,保存到aInfo/rInfo中,然後繼續調用startActivityLocked()函數處理後續流程:
    final int ActivityStarter::startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
        int err = ActivityManager.START_SUCCESS;

        ProcessRecord callerApp = null;//調用進程對應的ProcessRecord實例,這裏是Launcher進程
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);//Launcher進程所對應的ProcessRecord對象
            if (callerApp != null) {
                callingPid = callerApp.pid;//保存Launcher進程的pid和uid信息
                callingUid = callerApp.info.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller
                        + " (pid=" + callingPid + ") when starting: "
                        + intent.toString());
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }

        final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;

        if (err == ActivityManager.START_SUCCESS) {
            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
                    + "} from uid " + callingUid
                    + " on display " + (container == null ? (mSupervisor.mFocusedStack == null ?
                    Display.DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId) :
                    (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
                            container.mActivityDisplay.mDisplayId)));
        }

        ActivityRecord sourceRecord = null;//指向Launcher組件的一個ActivityRecord實例,它作爲source端
        ActivityRecord resultRecord = null;
        if (resultTo != null) {//resultTo對象指向了Launcher中一個Activity組件,這樣它AMS就可以知道需要把結果返回給哪個組件
            sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                    "Will send result to " + resultTo + " " + sourceRecord);
            if (sourceRecord != null) {
                if (requestCode >= 0 && !sourceRecord.finishing) {//如果需要返回結果,且啓動當前組件的那個Activity組件還未finish()
                    resultRecord = sourceRecord;//則sourceRecord則就是resultRecord
                }
            }
        }

        final int launchFlags = intent.getFlags();//得到新Activity組件的啓動標誌

        ...


        mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
        mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid,
                options);
        intent = mInterceptor.mIntent;
        rInfo = mInterceptor.mRInfo;
        aInfo = mInterceptor.mAInfo;
        resolvedType = mInterceptor.mResolvedType;
        inTask = mInterceptor.mInTask;
        callingPid = mInterceptor.mCallingPid;
        callingUid = mInterceptor.mCallingUid;
        options = mInterceptor.mActivityOptions;
        
	...

        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, voiceSession != null, mSupervisor, container,
                options, sourceRecord);//根據之前得到的一些信息,創建一個代表將要啓動的Activity的ActivityRecord對象
           ...
        try {
            mService.mWindowManager.deferSurfaceLayout();
            err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                    true, options, inTask);//繼續調用startActivityUnchecked();doResume爲true
        } finally {
            mService.mWindowManager.continueSurfaceLayout();
        }
       ...
    }
首先獲取到啓動當前Activity的進程信息,處理Launcher組件接收啓動結果的內容;最後根據一些參數初始化ActivityRecord對象,它代表了當前需要啓動的Activity在AMS中的存在形式;接着繼續調用startActivityUnchecked()函數進行處理:
    private int ActivityStarter::startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {

        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);//設置一些變量,保存到成員變量中;mDoResume根據參數被設置爲了true;mSourceRecord被設置成了sourceRecord,即將每次啓動當前Activity的組件保存起來;可以用在進程內啓動子Activity無需創建新棧的情況

        computeLaunchingTaskFlags();//mAddingToTask被置爲false

        computeSourceStack();

        mIntent.setFlags(mLaunchFlags);

        mReusedActivity = getReusableIntentActivity();
		...
        boolean newTask = false;
        final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.task : null;

        // Should this be considered a new task?
        if (mStartActivity.resultTo == null/*源Activity並不需要知道啓動結果*/ && mInTask == null && !mAddingToTask/*默認false*/
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {//從MAS::startActivityAsUser()調用傳入的inTask參數就是null;符合此項條件;mStartActivity指向當前正在啓動的Activity
            newTask = true;//需要創建新棧
            //由於該Activity的啓動參數設置爲FLAG_ACTIVITY_NEW_TASK,表明它運行在Launcher之外的任務中;該任務可以是新任務,也可以是某個存在的任務
            setTaskFromReuseOrCreateNewTask(taskToAffiliate);//如果Activity通過android:taskAffinity屬性設置了專屬任務,則會去查詢該任務是否存在,不存在則會創建它,並將該Activity運行在該任務中
            //創建了新的TaskRecord後,它會被保存到ActivityStack::mTaskHistory中,接下來就會進入ActivityStatck去啓動Activity

            if (mSupervisor.isLockTaskModeViolation(mStartActivity.task)) {
                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
            if (!mMovedOtherTask) {
                // If stack id is specified in activity options, usually it means that activity is
                // launched not from currently focused stack (e.g. from SysUI or from shell) - in
                // that case we check the target stack.
                updateTaskReturnToType(mStartActivity.task, mLaunchFlags,
                        preferredLaunchStackId != INVALID_STACK_ID ? mTargetStack : topStack);
            }
        } else if (mSourceRecord != null) {//如果走此分支,則表明當前的子Activity不需要創建新的任務棧去運行;所以它會運行在先前的任務棧中
            if (mSupervisor.isLockTaskModeViolation(mSourceRecord.task)) {
                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }

            final int result = setTaskFromSourceRecord();//將先前的任務棧設置給該Activity
            if (result != START_SUCCESS) {
                return result;
            }
        } 
		...
        mTargetStack.mLastPausedActivity = null;

        sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);

        mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);//調用ActivityStack::startActivityLocked()設置一些參數,例如將ActivityRecord放到它堆棧的頂端
        if (mDoResume) {
            
            final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                // If the activity is not focusable, we can't resume it, but still would like to
                // make sure it becomes visible as it starts (this will also trigger entry
                // animation). An example of this are PIP activities.
                // Also, we don't want to resume activities in a task that currently has an overlay
                // as the starting activity just needs to be in the visible paused state until the
                // over is removed.
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                // Go ahead and tell window manager to execute app transition for this activity
                // since the app transition will not be triggered through the resume channel.
                mWindowManager.executeAppTransition();
            } else {
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);//ActivityStackSupervisor::resumeFocusedStackTopActivityLocked()啓動Activity
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
        ...

        return START_SUCCESS;
    }
首先,先需要初始化一些變量。接着判斷當前啓動的Activity是否需要運行在一個單獨的任務棧中;由於我們設置了FLAG_ACTIVITY_NEW_TASK標誌,並且傳參的結果符合需要創建新任務棧的情況,所以會調用setTaskFromReuseOrCreateNewTask()爲當前Activity創建的新的任務棧(TaskRecord)。ActivityStack::startActivityLocked()函數中有一些需要注意的處理:
final void ActivityRecord::startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
            ActivityOptions options) {
        TaskRecord rTask = r.task;//該Activity所運行的任務
        final int taskId = rTask.taskId;
        // mLaunchTaskBehind tasks get placed at the back of the task 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);
            mWindowManager.moveTaskToTop(taskId);
        }
        TaskRecord task = null;
        if (!newTask) {//因爲創建了新的任務棧,所以newTas爲TRUE
			...
        }

        // Place a new activity at top of stack, so it is next to interact
        // with the user.

        task = r.task;

        // Slot the activity into the history stack and proceed
        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
                new RuntimeException("here").fillInStackTrace());
        task.addActivityToTop(r);//將本次啓動的Activity加入到該任務棧的mActivities列表的最頂端
        task.setFrontOfTask();//在此次的TaskRecord中,找到一個處於棧最頂端的ActivityRecord,並將它的frontOfTask設置爲true

        r.putInHistory();//設置inHistory標誌位
        ...
    }
該函數中會把當前需要啓動的Activity插入到它所屬的任務棧的頂端,這樣後面系統在處理啓動流程時,就可以檢查任務棧的頂端Activity,來獲取到當前需要啓動的Activity了。


接着調用ActivityStackSupervisor::resumeFocusedStackTopActivityLocked()函數繼續處理流程:

    boolean ActivityStackSupervisor::resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {//調用resumeTopActivityUncheckedLocked()
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);//調用ActivityStack::resumeTopActivityUncheckedLocked()
        }
        return false;
    }
	
	    boolean ActivityStack::resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);//resumeTopActivityInnerLocked()
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }
最終的處理會在ActivityStack::resumeTopActivityInnerLocked()之中:
private boolean ActivityStack::resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");

        if (!mService.mBooting && !mService.mBooted) {
            // Not ready yet!
            return false;
        }
		...
        // Find the first activity that is not finishing.
        final ActivityRecord next = topRunningActivityLocked();//找到當前Activity堆棧中第一個不是處於結束狀態的Activity,即爲即將要啓動的Activity

        final TaskRecord prevTask = prev != null ? prev.task : null;
        if (next == null) {//如果當前Task沒有Activity,顯示 Home Activity
            // There are no more activities!
            ...
        }

        next.delayedResume = false;

        // If the top activity is the resumed one, nothing to do.
        if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                    mStackSupervisor.allResumedActivitiesComplete()) {//如果要啓動的Activity就是當前已經resumed的Activity,則什麼都不做
            ...
            return false;
        }
        ...
        // If we are sleeping, and there is no resumed activity, and the top
        // activity is paused, well that is the state we want.
        if (mService.isSleepingOrShuttingDownLocked()
                && mLastPausedActivity == next
                && mStackSupervisor.allPausedActivitiesComplete()) {//如果系統正準備睡眠或關閉,直接退出
            // Make sure we have executed any pending transitions, since there
            // should be nothing left to do at this point.
            mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Going to sleep and all paused");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
		...
        // The activity may be waiting for stop, but that is no longer
        // appropriate for it.
        //將啓動的Activity從Stopping/GoingtoSleep/WaitingVisible等隊列移除
        mStackSupervisor.mStoppingActivities.remove(next);
        mStackSupervisor.mGoingToSleepActivities.remove(next);
        next.sleeping = false;
        mStackSupervisor.mWaitingVisibleActivities.remove(next);

        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);

        // If we are currently pausing an activity, then don't do anything until that is done.
        if (!mStackSupervisor.allPausedActivitiesComplete()) {//如果系統當前還有暫停的Activity,先退出
            ...
            return false;
        }

        // We need to start pausing the current activity so the top one can be resumed...
        final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
        if (mResumedActivity != null) {//需要先暫停當前顯示的Activity,此時它指向Launcher,再顯示新的Activity;如果Activity已經處理了paused狀態,mResumedActivity會被重置爲null
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);//將Launcher切換至Paused狀態,再返回來顯示新的Activity
        }
        if (pausing) {//如果系統還有正在暫停的Activity,先退出
            ...
            return true;
        } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                mStackSupervisor.allResumedActivitiesComplete()) {
            ...
        }

        // Launching this app's activity, make sure the app is no longer
        // considered stopped.
        try {
            AppGlobals.getPackageManager().setPackageStoppedState(
                    next.packageName, false, next.userId); /* TODO: Verify if correct userid */
        } catch (RemoteException e1) {
        } catch (IllegalArgumentException e) {
            Slog.w(TAG, "Failed trying to unstop package "
                    + next.packageName + ": " + e);
        }
		...
        ActivityStack lastStack = mStackSupervisor.getLastStack();
        if (next.app != null && next.app.thread != null) {//如果這個Activity所在的應用進程已經存在,只需要把Activity顯示出來
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
                    + " stopped=" + next.stopped + " visible=" + next.visible);
			...
            try {
                // Deliver all pending results.
                ArrayList<ResultInfo> a = next.results;
                if (a != null) {
                    final int N = a.size();
                    if (!next.finishing && N > 0) {
                        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                                "Delivering results to " + next + ": " + a);
                        next.app.thread.scheduleSendResult(next.appToken, a);
                    }
                }

                boolean allowSavedSurface = true;
                if (next.newIntents != null) {//如果是特殊的幾種重啓Activity的情況,先調用應用的onNewIntent()
                    // Restrict saved surface to launcher start, or there is no intent at all
                    // (eg. task being brought to front). If the intent is something else,
                    // likely the app is going to show some specific page or view, instead of
                    // what's left last time.
                    for (int i = next.newIntents.size() - 1; i >= 0; i--) {
                        final Intent intent = next.newIntents.get(i);
                        if (intent != null && !ActivityRecord.isMainIntent(intent)) {
                            allowSavedSurface = false;
                            break;
                        }
                    }
                    next.app.thread.scheduleNewIntent(
                            next.newIntents, next.appToken, false /* andPause */);//調用應用的onNewIntent()
                }
				...
                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                        mService.isNextTransitionForward(), resumeAnimOptions);//調用應用進程該Activity的onResume()直接把它顯示出來

				
            } catch (Exception e) {
                // Whoops, need to restart this activity!
               ...
            }
           ...
        } else {//如果Activiy所在的應用還未啓動,則先啓動應用,爲它創建應用進程
			...
            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true);//startSpecificActivityLocked(),此時,如果應用進程已經啓動,則會去直接啓動Activity;否則,先爲它啓動一個進程
        }

        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }
我們知道,系統在啓動一個 新的Activity時,會將之前顯示的Activitypause掉,再將當前的Activity resume並顯示給用戶;這其中就涉及到Activity生命週期變化的過程。


ActivityStack有幾個成員變量控制了這個過程,它們的含義大致如下:


  • ActivityRecord mPausingActivity:在啓動下一個Activity之前,系統正在pause的Activity
  • ActivityRecord mLastPausedActivity:系統最近處理地已經進入paused狀態的Activity
  • ActivityRecord mResumedActivity:系統當前正在顯示、與用戶直接交互的Activity
  • ActivityRecord mLastStartedActivity:系統最近啓動完成的Activity


首先調用topRunningActivityLocked()函數找到當前Activity堆棧中第一個不是處於結束狀態的Activity,即爲即將要啓動的Activity,保存到next變量中。我們是在Launcher中啓動一個新應用Activity的,此時系統處於resumed狀態的Activity就是Launcher,即mResumedActivity不爲null,並指向Launcher組件;所以,此時我們需要先暫停Launcher組件的Activity;再去啓動當前新的Activity,這部分處理是調用startPausingLocked()函數實現的。


如果當前系統正在處理Activity的pause過程,則此時會先退出當前處理。之後,會先判斷當前啓動需要啓動的Activity,它的應用進程是否已經被創建了,如果是,則會直接去resume該Activity;否則,需要先爲當前的Activity創建一個新的應用進程,再去處理它的啓動工作。


我們來看Launcher組件被pause的過程,直接看startPausingLocked()函數的處理:

/**
     * Start pausing the currently resumed activity.  It is an error to call this if there
     * is already an activity being paused or there is no resumed activity.
     *
     * @param userLeaving True if this should result in an onUserLeaving to the current activity.
     * @param uiSleeping True if this is happening with the user interface going to sleep (the
     * screen turning off).
     * @param resuming The activity we are currently trying to resume or null if this is not being
     *                 called as part of resuming the top activity, so we shouldn't try to instigate
     *                 a resume here if not null.
     * @param dontWait True if the caller does not want to wait for the pause to complete.  If
     * set to true, we will immediately complete the pause here before returning.
     * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
     * it to tell us when it is done.
     */
    final boolean ActivityStack::startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean dontWait) {
        if (mPausingActivity != null) {
            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
                    + " state=" + mPausingActivity.state);
            if (!mService.isSleepingLocked()) {
                // Avoid recursion among check for sleep and complete pause during sleeping.
                // Because activity will be paused immediately after resume, just let pause
                // be completed by the order of activity paused from clients.
                completePauseLocked(false, resuming);
            }
        }
        ActivityRecord prev = mResumedActivity;//當前已經Resume的Activity是Launcher中的組件,先保存一份
		...
		//mResumedActivity設置爲null,並將mPausingActivity/mLastPausedActivity設置爲即將要進入pause狀態的Launcher組件
        mResumedActivity = null;
        mPausingActivity = prev;//當前正在進入Pause狀態的組件是Launcher組件
        mLastPausedActivity = prev;//當前正在進入Pause狀態的組件是Launcher組件
        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
        prev.state = ActivityState.PAUSING;
        prev.task.touchActiveTime();//將prev的狀態設置爲PAUSING
        ...
        if (prev.app != null && prev.app.thread != null) {//因爲Launcher已經運行了,所以它的進程一定存在
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
            try {
                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                        prev.userId, System.identityHashCode(prev),
                        prev.shortComponentName);
                mService.updateUsageStats(prev, false);
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);//調用Launcher組件的onPause()方法,進入paused狀態
            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }  
		...
        if (mPausingActivity != null) {
            ...
            if (dontWait) {
                // If the caller said they don't want to wait for the pause, then complete
                // the pause now.
                completePauseLocked(false, resuming);
                return false;

            } else {//向AMS發送一個Pause超時的延時消息,以便AMS處理Launcher組件長時間未響應的情況
                // Schedule a pause timeout in case the app doesn't respond.
                // We don't give it much time because this directly impacts the
                // responsiveness seen by the user.
                Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
                msg.obj = prev;
                prev.pauseTime = SystemClock.uptimeMillis();
                mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
                return true;
            }

        } else {
            ...
            return false;
        }
    }
首先會重置ActivityStack中一些變量的狀態,mResumedActivity置爲null,mPausingActivity/mLastPausedActivity則指向當前正在進入pause狀態的組件,即Launcher。緊接着進入Launcher組件的主線程中處理Activity的pause過程。


prev是ActivityRecord類型,它的成員app是ProcessRecord對象,描述了當前Activity所運行在的進程的信息;ProcessRecord的成員thread是IApplicationThread類型,它用於AMS和應用進程之間進行通信,實際指向ApplicationThread服務的Client端實例:ApplicationThreadProxy;這樣AMS只要通過一個Activity所代表的ActivityRecord對象就可以和Activity所屬的進程和主線程進行交互了;AMS所有跟生命週期相關的處理都是以此種方式跟應用進程交互的。


IApplicationThread家族的繼承關係類圖大致如下所示:


圖中的ActivityThread類型就是代表應用進程的主線程;AMS爲應用創建進程時,會指定ActivityThread的入口函數爲整個進程的入口函數,並在其中做一些全局初始化工作。
這樣我們就基本瞭解AMS是如何與應用進程交互的了。那麼,我們直接看這部分的代碼處理過程:

    public final void ApplicationThreadProxy::schedulePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeStrongBinder(token);
        data.writeInt(finished ? 1 : 0);
        data.writeInt(userLeaving ? 1 :0);
        data.writeInt(configChanges);
        data.writeInt(dontReport ? 1 : 0);
        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }
	
	 @Override
    public boolean ApplicationThreadNative::onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            IBinder b = data.readStrongBinder();
            boolean finished = data.readInt() != 0;
            boolean userLeaving = data.readInt() != 0;
            int configChanges = data.readInt();
            boolean dontReport = data.readInt() != 0;
            schedulePauseActivity(b, finished, userLeaving, configChanges, dontReport);
            return true;
        }
		...
	}
	
/**
 * This manages the execution of the main thread in an
 * application process, scheduling and executing activities,
 * broadcasts, and other operations on it as the activity
 * manager requests.
 *
 * {@hide}
 */
public final class ActivityThread {

	final H mH = new H();
	
	private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
        if (DEBUG_MESSAGES) Slog.v(
                TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 +
                        "seq= " + seq);
        Message msg = Message.obtain();
        msg.what = what;
        SomeArgs args = SomeArgs.obtain();
        args.arg1 = obj;
        args.argi1 = arg1;
        args.argi2 = arg2;
        args.argi3 = seq;
        msg.obj = args;
        mH.sendMessage(msg);
    }
	
	private class ApplicationThread extends ApplicationThreadNative {
 
        public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            int seq = getLifecycleSeq();
            if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
                    + " operation received seq: " + seq);
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
                    configChanges,
                    seq);
        }
	}
	
	private class H extends Handler {
		public void handleMessage(Message msg) {
			...
		}
	}
}
最終處理pause的過程是向ActivityThread::H發送了一個PAUSE消息,直接看這部分的處理:
 public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
				...
                case PAUSE_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, false,
                            (args.argi1 & USER_LEAVING) != 0, args.argi2,
                            (args.argi1 & DONT_REPORT) != 0, args.argi3);
                    maybeSnapshot();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
				
			}				
	}
原來是直接調用handlePauseActivity()函數進行處理:
   private void ActivityThread::handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
        ActivityClientRecord r = mActivities.get(token);
        if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
        if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
            return;
        }
        if (r != null) {
            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
            if (userLeaving) {
                performUserLeavingActivity(r);
            }

            r.activity.mConfigChangeFlags |= configChanges;
            performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");//調用performPauseActivity()

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

            // Tell the activity manager we have paused.
            if (!dontReport) {
                try {
                    ActivityManagerNative.getDefault().activityPaused(token);//將已經進入Paused狀態的Activity的結果告知AMS
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }
            mSomeActivitiesChanged = true;
        }
    }
直接看performPauseActivity()函數:
    final Bundle performPauseActivity(IBinder token, boolean finished,
            boolean saveState, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
    }

    final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
            boolean saveState, String reason) {
        if (r.paused) {
            if (r.activity.mFinished) {
                // If we are finishing, we won't call onResume() in certain cases.
                // So here we likewise don't want to call onPause() if the activity
                // isn't resumed.
                return null;
            }
            RuntimeException e = new RuntimeException(
                    "Performing pause of activity that is not resumed: "
                    + r.intent.getComponent().toShortString());
            Slog.e(TAG, e.getMessage(), e);
        }
        if (finished) {
            r.activity.mFinished = true;
        }

        // Next have the activity save its current state and managed dialogs...
        if (!r.activity.mFinished && saveState) {
            callCallActivityOnSaveInstanceState(r);
        }

        performPauseActivityIfNeeded(r, reason);//調用performPauseActivityIfNeeded()

        // 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 !r.activity.mFinished && saveState ? r.state : null;
    }

ActivityThread::mActivities成員以IBinder爲鍵值,保存了所有運行在該應用進程之中的Activity;每個Activity以ActivityClientRecord類型表示。


在主線程中根據mToken實例找到了代表當前需要進入pause狀態的Activity對應的ActivityClientRecord實例後,調用performPauseActivityIfNeeded()函數處理該Activity的onPause(),隨後並將當前Activity的處理結果反饋給AMS;直接看:

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

        try {
            r.activity.mCalled = false;
            mInstrumentation.callActivityOnPause(r.activity);//調用當前即將進入pause狀態的Activity::onPause()
            EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
                    r.activity.getComponentName().getClassName(), reason);
            if (!r.activity.mCalled) {
                throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                        + " did not call through to super.onPause()");
            }
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException("Unable to pause activity "
                        + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
            }
        }
        r.paused = true;//再將該Activity的paused置爲true,表明它已經進入了paused狀態
    }
通過Instrumentation調用該Activity的onPause()函數:
    private void ActivityThread::performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
        if (r.paused) {
            // You are already paused silly...
            return;
        }

        try {
            r.activity.mCalled = false;
            mInstrumentation.callActivityOnPause(r.activity);//調用當前即將進入pause狀態的Activity::onPause()
            EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
                    r.activity.getComponentName().getClassName(), reason);
            if (!r.activity.mCalled) {
                throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                        + " did not call through to super.onPause()");
            }
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException("Unable to pause activity "
                        + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
            }
        }
        r.paused = true;//再將該Activity的paused置爲true,表明它已經進入了paused狀態
    }
	
	/**
     * 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 Instrumentation::callActivityOnPause(Activity activity) {
        activity.performPause();
    }
	
	final void Activity::performPause() {
        mDoReportFullyDrawn = false;
        mFragments.dispatchPause();
        mCalled = false;
        onPause(); //調用了當前Activity所屬的onPause()函數
        mResumed = false;
        if (!mCalled && getApplicationInfo().targetSdkVersion
                >= android.os.Build.VERSION_CODES.GINGERBREAD) {
            throw new SuperNotCalledException(
                    "Activity " + mComponent.toShortString() +
                    " did not call through to super.onPause()");
        }
        mResumed = false;
    }
隨後在將當前已經進入pause狀態的Activity的狀態也設置爲paused;至此,Launcher Activity組件進入pause狀態的處理就結束了。這一部分的處理流程有一定的共同性,後續再分析這部分內容時,就會跳過一些Binder調用的過程,以簡化分析過程。


Launcher組件的Activity進入pause狀態後,還需要將結果反饋給AMS:

private void ActivityThread::handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
			
			...

            // Tell the activity manager we have paused.
            if (!dontReport) {
                try {
                    ActivityManagerNative.getDefault().activityPaused(token);//將已經進入Paused狀態的Activity的結果告知AMS
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }
            mSomeActivitiesChanged = true;
        }
    }
傳入的參數是代表Launcher組件的一個IBinder對象,AMS可以根據該實例找到對應的ActivityRecord實例;直接分析AMS::activityPaused()函數:
    @Override
    public final void ActivityManagerService::activityPaused(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityPausedLocked(token, false);//調用activityPausedLocked()
            }
        }
        Binder.restoreCallingIdentity(origId);
    }
其中涉及到的Binder通信的部分,可以參考之前的分析過程。直接調用ActivityStack::activityPausedLocked()函數:
    final void ActivityStack::activityPausedLocked(IBinder token, boolean timeout) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
            "Activity paused: token=" + token + ", timeout=" + timeout);

        final ActivityRecord r = isInStackLocked(token);//根據token找到任務棧中Launcher對應的組件
        if (r != null) {
            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);//移除之前發送的PAUSE_TIMEOUT_MSG消息;因爲該組件已經在規定的時間內進入pause成功了
            if (mPausingActivity == r) {//mPausingActivity之前設置過,它此時也指向Launcher組件
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                        + (timeout ? " (due to timeout)" : " (pause complete)"));
                completePauseLocked(true, null);//參數resumeNext值爲true
                return;
            } else {
               ...
            }
        }
        ...
    }
首先根據token參數找到對應的Launcher組件的ActivityRecord對象,因爲之前的處理過程mPausingActivity已經執行了Launcher組件,所以此時會移除之前發送的處理pause超時的消息,並調用completePauseLocked()函數處理後續新Activity的啓動過程:
    private void ActivityStack::completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
        ActivityRecord prev = mPausingActivity;//在處理pause狀態是,該成員已經被設置過,不會爲null
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);

        if (prev != null) {
            final boolean wasStopping = prev.state == ActivityState.STOPPING;
            prev.state = ActivityState.PAUSED;
            if (prev.finishing) {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
            } else if (prev.app != null) {
               ...
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
                prev = null;
            }
            ...
            mPausingActivity = null;//最後重置mPausingActivity狀態,因爲此時Launcher已經是paused了
        }

        if (resumeNext) {//爲true
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!mService.isSleepingOrShuttingDownLocked()) {//如果此時設備未處於休眠或關閉狀態,則去啓動位於Activity組件堆棧頂端的Activity
                mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);//調用resumeFocusedStackTopActivityLocked()去啓動任務棧頂端的Activity
            } else {
                mStackSupervisor.checkReadyForSleepLocked();
                ActivityRecord top = topStack.topRunningActivityLocked();
                if (top == null || (prev != null && top != prev)) {
                    // If there are no more activities available to run, do resume anyway to start
                    // something. Also if the top activity on the stack is not the just paused
                    // activity, we need to go ahead and resume it to ensure we complete an
                    // in-flight app switch.
                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
                }
            }
        }
		...
    }
resumeNext參數傳入的值爲true;首先會清空一些狀態,將mPausingActivity指向的Activity狀態設置爲PAUSED,隨後並置爲null。接着調用ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()函數去啓動當前任務棧頂端的Activity,即目標Activity:
    boolean ActivityStackSupervisor::resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {//調用resumeTopActivityUncheckedLocked()
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);//調用resumeTopActivityUncheckedLocked()
        }
        return false;
    }
	
	boolean ActivityStack::resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);//resumeTopActivityInnerLocked()
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }
與先前一樣,還是進入ActivityStack::resumeTopActivityInnerLocked()函數:
    private boolean ActivityStack::resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");

		...
        // Find the first activity that is not finishing.
        final ActivityRecord next = topRunningActivityLocked();//找到當前Activity堆棧中第一個不是處於結束狀態的Activity,即爲即將要啓動的Activity

        ...

        // We need to start pausing the current activity so the top one can be resumed...
        final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
        if (mResumedActivity != null) {//需要先暫停當前顯示的Activity,此時它指向Launcher,再顯示新的Activity;如果Activity已經處理了paused狀態,mResumedActivity會被重置爲null
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);//將Launcher切換至Paused狀態,再返回來顯示新的Activity
        }
        if (pausing) {//如果系統還有正在暫停的Activity,先退出
            ...
        } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
            ...
        }

		...
        ActivityStack lastStack = mStackSupervisor.getLastStack();
        if (next.app != null && next.app.thread != null) {//如果這個Activity所在的應用進程已經存在,只需要把Activity顯示出來
            ...
        } else {//如果Activiy所在的應用還未啓動,則先啓動應用
            ...
            mStackSupervisor.startSpecificActivityLocked(next, true, true);//startSpecificActivityLocked(),此時,如果應用進程已經啓動,則會去直接啓動Activity;否則,先爲它啓動一個進程
        }

        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }
根據之前的處理,mResumedActivity/mPausingActivity都以置爲null;因爲,我們需要啓動的Activity它的應用進程並未創建過,所以這裏需要爲它創建一個應用進程:
    void ActivityStackSupervisor::startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                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.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);//如果應用進程已經啓動了,則調用該函數繼續處理;其會觸發類的onCreate()方法
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

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

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);//應用進程沒有啓動,則去啓動應用進程
    }

因爲我們的應用並未啓動過,所以需要爲它創建應用,這是通過ASM::startProcessLocked()處理的;否則,當前應用進程已經啓動過,此時只需要直接啓動當前Activity即可,這部分由realStartActivityLocked()處理。


AMS爲應用創建進程是藉助fork機制實現的,並指定了應用進程的入口函數是ActivityThread::main(),這部分內容會在後續的文章中分析;當系統進程創建工作完成後,就會進入ActivityThread::main()函數:

	//應用進程的入口函數
    public static void ActivityThread::main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        SamplingProfilerIntegration.start();

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

        Environment.initForCurrentUser();

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

        ActivityThread thread = new ActivityThread();//創建ActivityThread對象
        thread.attach(false);//調用attach()向AMS發送一個進程啓動完成通知

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

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

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();//開啓消息循環

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
這裏主要創建了ActivityThread實例並調用了attach()函數,緊接着並啓動了消息循環。ActivityThread的構造函數並沒有什麼重要的工作,我們主要看attach()函數的實現:
   private void ActivityThrad::attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {//傳參爲false
			...
            RuntimeInit.setApplicationObject(mAppThread.asBinder());//將ApplicationThread對象添加到RuntimeInit中
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);//調用AMS::attachApplication(),表明當次想要啓動的應用進程已經啓動完畢;參數是ApplicationThread對象,它用於AMS和ActivityThread所在的進程之間的通信
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
			...
        } else {
            ...
        }
        ...
    }
調用了AMS::attachApplication()函數,告知AMS當前爲應用新創建的進程已經準備好了,可以開始啓動Activity了;mAppThread的定義是:
final ApplicationThread mAppThread = new ApplicationThread();
將它傳遞給AMS,AMS就可以通過它與該新創建的應用進程和主線程交互了。我們看AMS::attachApplication()函數的實現:
    @Override
    public final void AMS::attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);//調用attachApplicationLocked()
            Binder.restoreCallingIdentity(origId);
        }
    }
	
	  private final boolean AMS::attachApplicationLocked(IApplicationThread thread,
            int pid) {

        // Find the application record that is being attached...  either via
        // the pid if we are running in multiple processes, or just pull the
        // next app record if we are emulating process with anonymous threads.
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);//創建應用進程時,會將進程對象和pid保存到mPidsSelfLocked集合中,所以此時可以取出對應的進程對象
            }
        } else {
            app = null;
        }

        if (app == null) {
            ...
        }

        // If this application record is still attached to a previous
        // process, clean it up now.
        if (app.thread != null) {//如果app中已經有線程,說明app以前存在,現在是重啓;先清理掉這些信息
            handleAppDiedLocked(app, true, true);
        }

        final String processName = app.processName;
        try {
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);//創建app死亡監聽對象
            thread.asBinder().linkToDeath(adr, 0);
            app.deathRecipient = adr;
        } catch (RemoteException e) {
            app.resetPackageList(mProcessStats);
            startProcessLocked(app, "link fail", processName);
            return false;
        }

        app.makeActive(thread, mProcessStats);//會將創建的ActivityThread對應的ApplicationThread對象的Binder實例保存到該ProcessRecord對象的thread成員中,用以和該進程的主線程交互
        ...

        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);

		...
        try {
			...
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());//調用bindApplication()方法
            updateLruProcessLocked(app, false, null);
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {
           ...
        }

        // Remove this record from the list of starting applications.
        mPersistentStartingProcesses.remove(app);
        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
                "Attach application locked removing on hold: " + app);
        mProcessesOnHold.remove(app);

        boolean badApp = false;
        boolean didSomething = false;

        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {//調用attachApplicationLocked(),去啓動當前Activity組件堆棧最頂端的Activity
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
		...
        return true;
	}

首先會調用thread的bindApplication()函數,它會做一些應用共用的初始化動作,直接看它在ActivityThread中的處理:

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

            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;
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            sendMessage(H.BIND_APPLICATION, data);
        }
		
		
    private void ActivityThread::handleBindApplication(AppBindData data) {
        // Register the UI Thread as a sensitive thread to the runtime.
        VMRuntime.registerSensitiveThread();
        ...
		data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);//初始化LoadedApk對象
		...
        // Instrumentation info affects the class loader, so load it before
        // setting up the app context.
        final InstrumentationInfo ii;
        if (data.instrumentationName != null) {//如果應用指定了自己的Instrumentation,則去初始化它;否則,直接創建Instrumentation實例
            try {
                ii = new ApplicationPackageManager(null, getPackageManager())
                        .getInstrumentationInfo(data.instrumentationName, 0);
            } catch (PackageManager.NameNotFoundException e) {
                throw new RuntimeException(
                        "Unable to find instrumentation info for: " + data.instrumentationName);
            }

            mInstrumentationPackageName = ii.packageName;
            mInstrumentationAppDir = ii.sourceDir;
            mInstrumentationSplitAppDirs = ii.splitSourceDirs;
            mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
            mInstrumentedAppDir = data.info.getAppDir();
            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
            mInstrumentedLibDir = data.info.getLibDir();
        } else {
            ii = null;
        }

        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);//生成ContextImpl對象
        updateLocaleListFromAppContext(appContext,
                mResourcesManager.getConfiguration().getLocales());
        ...

        // Continue loading instrumentation.
        if (ii != null) {如果應用指定了自己的Instrumentation類型,則去初始化它;否則,直接創建Instrumentation實例
            final ApplicationInfo instrApp = new ApplicationInfo();
            ii.copyTo(instrApp);
            instrApp.initForUser(UserHandle.myUserId());
            final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                    appContext.getClassLoader(), false, true, false);
            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

            try {
                final ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {
                throw new RuntimeException(
                    "Unable to instantiate instrumentation "
                    + data.instrumentationName + ": " + e.toString(), e);
            }

            final ComponentName component = new ComponentName(ii.packageName, ii.name);
            mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);

            if (mProfiler.profileFile != null && !ii.handleProfiling
                    && mProfiler.profileFd == null) {
                mProfiler.handlingProfiling = true;
                final File file = new File(mProfiler.profileFile);
                file.getParentFile().mkdirs();
                Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
            }
        } else {
            mInstrumentation = new Instrumentation();
        }
        ...
        try {
            // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;

            ...
            // Do this after providers, since instrumentation tests generally start their
            // test thread at this point, and we don't want that racing.
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {
              ...
            }

            try {
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
               ...
            }
        } finally {
            StrictMode.setThreadPolicy(savedPolicy);
        }
    }
	
	public final LoadedApk ActivityThread::getPackageInfoNoCheck(ApplicationInfo ai,
            CompatibilityInfo compatInfo) {
        return getPackageInfo(ai, compatInfo, null, false, true, false);
    }
	
	private LoadedApk ActivityThread::getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
            ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
            boolean registerPackage) {
        final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
        synchronized (mResourcesManager) {
            WeakReference<LoadedApk> ref;
            if (differentUser) {
                // Caching not supported across users
                ref = null;
            } else if (includeCode) {
                ref = mPackages.get(aInfo.packageName);
            } else {
                ref = mResourcePackages.get(aInfo.packageName);
            }

            LoadedApk packageInfo = ref != null ? ref.get() : null;
            if (packageInfo == null || (packageInfo.mResources != null
                    && !packageInfo.mResources.getAssets().isUpToDate())) {
                if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
                        : "Loading resource-only package ") + aInfo.packageName
                        + " (in " + (mBoundApplication != null
                                ? mBoundApplication.processName : null)
                        + ")");
                packageInfo =
                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
                            securityViolation, includeCode &&
                            (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);

                if (mSystemThread && "android".equals(aInfo.packageName)) {
                    packageInfo.installSystemApplicationInfo(aInfo,
                            getSystemContext().mPackageInfo.getClassLoader());
                }

                if (differentUser) {
                    // Caching not supported across users
                } else if (includeCode) {
                    mPackages.put(aInfo.packageName,
                            new WeakReference<LoadedApk>(packageInfo));
                } else {
                    mResourcePackages.put(aInfo.packageName,
                            new WeakReference<LoadedApk>(packageInfo));
                }
            }
            return packageInfo;
        }
    }

	public Application LoadedApk::makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

        ...
        Application app = null;

        ...
        try {
            ...
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
           ...
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
               ...
            }
        }
        ...
        return app;
    }
從代碼可以得知,一個ActivityThread對象,即一個應用的主線程中只會存在一個LoadedApk、Instrumentation、Application等實例,它們在一個應用進程中被所有Activity共用。

接着調用ActivityStackSupervisor.attachApplicationLocked()在該進程啓動當前的目標Activity:

    boolean ActivityStackSupervisor::attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFocusedStack(stack)) {
                    continue;
                }
                ActivityRecord hr = stack.topRunningActivityLocked();//得到Activity堆棧最頂端的Activity,去啓動它
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {//該Activity的app爲null,且它的uid和進程名都與此次的進程相同,表明這個進程就是爲該Activity創建的;則去啓動該Activity
                        try {
                            if (realStartActivityLocked(hr, app, true, true)) {//啓動這個Activity
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                  + hr.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {//如果Activity堆棧對頂端的組件已經啓動,但是窗口沒有顯示出來,則去顯示它
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
        return didSomething;
    }
首先得到當前任務棧頂端的Activity,它既是我們當前需要啓動的目標。因爲該Activity尚未啓動,所以會去調用realStartActivityLocked()去啓動:
	final boolean ActivityStackSupervisor::realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {

		...
	
        r.app = app;
        app.waitingToKill = null;
        r.launchCount++;
        r.lastLaunchTime = SystemClock.uptimeMillis();

        if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);

        int idx = app.activities.indexOf(r);
        if (idx < 0) {
            app.activities.add(r);//將此次啓動的Activity添加到該進程的activities列表中,它保存了所有運行在該進程中的Activity信息
        }
        ...

        final ActivityStack stack = task.stack;
        try {
            ...

            if (andResume) {
                app.hasShownUi = true;
                app.pendingUiClean = true;
            }
            ...
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);//調用ActivityThread中的handleLaunchActivity()函數去launch一個Activity,AMS與ActivityThread通信要藉助ApplicationThread對象

           ...

        } catch (RemoteException e) {
            ...
        }

        r.launchFailed = false;

        ...

        return true;
    }
將會調用前面提到的IApplicationThread對象的scheduleLaunchActivity()函數去launch當前的Activity:
 public final void ApplicationThreadProxy::scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
            CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
            int procState, Bundle state, PersistableBundle persistentState,
            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
            boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        intent.writeToParcel(data, 0);
        data.writeStrongBinder(token);
        data.writeInt(ident);
        info.writeToParcel(data, 0);
        curConfig.writeToParcel(data, 0);
        if (overrideConfig != null) {
            data.writeInt(1);
            overrideConfig.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        compatInfo.writeToParcel(data, 0);
        data.writeString(referrer);
        data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null);
        data.writeInt(procState);
        data.writeBundle(state);
        data.writePersistableBundle(persistentState);
        data.writeTypedList(pendingResults);
        data.writeTypedList(pendingNewIntents);
        data.writeInt(notResumed ? 1 : 0);
        data.writeInt(isForward ? 1 : 0);
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }
	
	    @Override
    public boolean ApplicationThreadNative::onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {

		case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            Intent intent = Intent.CREATOR.createFromParcel(data);
            IBinder b = data.readStrongBinder();
            int ident = data.readInt();
            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
            Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
            Configuration overrideConfig = null;
            if (data.readInt() != 0) {
                overrideConfig = Configuration.CREATOR.createFromParcel(data);
            }
            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
            String referrer = data.readString();
            IVoiceInteractor voiceInteractor = IVoiceInteractor.Stub.asInterface(
                    data.readStrongBinder());
            int procState = data.readInt();
            Bundle state = data.readBundle();
            PersistableBundle persistentState = data.readPersistableBundle();
            List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
            List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR);
            boolean notResumed = data.readInt() != 0;
            boolean isForward = data.readInt() != 0;
            ProfilerInfo profilerInfo = data.readInt() != 0
                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
            scheduleLaunchActivity(intent, b, ident, info, curConfig, overrideConfig, compatInfo,
                    referrer, voiceInteractor, procState, state, persistentState, ri, pi,
                    notResumed, isForward, profilerInfo);
            return true;
        }
	}
直接調用ApplicationThread::scheduleLauncherActivity:
        // we use token to identify this activity without having to send the
        // activity itself back to the activity manager. (matters more with ipc)
        @Override
        public final void ApplicationThread::scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();//創建ActivityClientRecord對象,並進行初始化

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

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

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

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
		
		 public void ActivityThrad::H::handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
			            case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
			}
		}
首先會將AMS傳入的參數封裝成ActivityClientRecord對象,然後調用ActivityThread::handleLaunchActivity():

  private void ActivityThread::handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ...
        Activity a = performLaunchActivity(r, customIntent);//調用performLaunchActivity(),過程中會執行Activity::onCreate()和onStart()方法

        if (a != null) {
			...
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);//調用handleResumeActivity(),過程中會執行Activity::onResume()方法
					
			if (!r.activity.mFinished && r.startsNotResumed) {
                // The activity manager actually wants this one to start out paused, because it
                // needs to be visible but isn't in the foreground. We accomplish this by going
                // through the normal startup (because activities expect to go through onResume()
                // the first time they run, before their window is displayed), and then pausing it.
                // However, in this case we do -not- need to do the full pause cycle (of freezing
                // and such) because the activity manager assumes it can just retain the current
                // state it has.
                performPauseActivityIfNeeded(r, reason);

                // We need to keep around the original state, in case we need to be created again.
                // But we only do this for pre-Honeycomb apps, which always save their state when
                // pausing, so we can not have them save their state when restarting from a paused
                // state. For HC and later, we want to (and can) let the state be saved as the
                // normal part of stopping the activity.
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        } else {
            ...
        }
    }
分別會調用performLaunchActivity()和handleResumeActivity()來完成當前啓動Activity的初始化及生命週期調用工作;首先看performLaunchActivity():
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();//該Activity的組件名稱,全限定名
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

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

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);//首先通過Instrumentation加載這個Activity所在的類,並創建一個它的實例
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
           ...
        }

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

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
			...

            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);//爲該Activity創建ContextImple實例,初始化它的上下文環境
                ...
                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);//Activity::attach()調用

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
				...
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);//通過Instrumentation調用該Activity的onCreate()函數
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                r.stopped = true;//將stopped置爲TRUE,在調用onStart()之前,Activity::stopped都是true;
                if (!r.activity.mFinished) {//mFinished只會在Activiy調用了finish()方法之後,纔會被置爲true
                    activity.performStart();//在執行Activity::onResume()之前會去調用Activity::onStart()方法;調用Activity::onStart()方法
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;

            mActivities.put(r.token, r);//token實際是指向一個AMS中的ActivityRecord實例,代表當前啓動的Activity;將此次ActivityClientRecord對象保存到Map中

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            ...
        }

        return activity;
    }

首先獲取當前Activity的全限定名,並通過ClassLoader來加載當前的Activity類,並創建該Activity的一個實例;隨後會爲當前應用創建上下文對象及其他信息,並與該Activity關聯起來;這部分內容,後續再分析,此處我們只關注Activity生命週期相關的內容。接着:


  • Instrumentation.callActivityOnCreate()函數會根據當前Activity的實例去調用它的onCreate()函數
  • Activity.performStart()函數會去調用當前Activity的onStart()函數
  • 會將當前當前啓動的Activity信息保存到ActivityThread::mActivities集合中


即:

    /**
     * Perform calling of an activity's {@link Activity#onCreate}
     * method.  The default implementation simply calls through to that method.
     *
     * @param activity The activity being created.
     * @param icicle The previously frozen state (or null) to pass through to onCreate().
     */
    public void Instrumentation::callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
	
	final void Activity::performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle);//onCreate()調用
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }
	
	//------------------------------------------------
	
	final void Activity::performStart() {
		...
        mInstrumentation.callActivityOnStart(this);
        ...
    }
	
	    /**
     * Perform calling of an activity's {@link Activity#onStart}
     * method.  The default implementation simply calls through to that method.
     * 
     * @param activity The activity being started.
     */
    public void Instrumentation::callActivityOnStart(Activity activity) {
        activity.onStart();//onStart()調用
    }

返回到ActivityThread::handleLaunchActivity(),隨後會繼續調用ActivityThread::handleResumeActivity()函數:

    final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
        ActivityClientRecord r = mActivities.get(token);//根據之前保存到Map中的信息獲取當前Activity的ActivityClientRecord對象
        if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
            return;
        }

		...

        // TODO Push resumeArgs into the activity for consideration
        r = performResumeActivity(token, clearHide, reason);//會藉助Instrumentation.callActivityOnResume()函數調用當前Activity::onResume()

        if (r != null) {
            ...

            if (!r.onlyLocalRequest) {
                r.nextIdle = mNewActivities;
                mNewActivities = r;
                if (localLOGV) Slog.v(
                    TAG, "Scheduling idle handler for " + r);
                Looper.myQueue().addIdleHandler(new Idler());//使用了Idle(IdleHandler)空閒消息處理器
            }
            r.onlyLocalRequest = false;

            // Tell the activity manager we have resumed.
            if (reallyResume) {
                try {
                    ActivityManagerNative.getDefault().activityResumed(token);//通知Activity已經resumed
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }

        } else {
            ...
        }
    }
performResumeActivity()函數會導致Activity::onResume()被調用:
    public final ActivityClientRecord ActivityThread::performResumeActivity(IBinder token,
            boolean clearHide, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        if (localLOGV) Slog.v(TAG, "Performing resume of " + r
                + " finished=" + r.activity.mFinished);
        if (r != null && !r.activity.mFinished) {
			...
            try {
               ...
                r.activity.performResume();

                ...

                r.paused = false;
                r.stopped = false;
                r.state = null;
                r.persistentState = null;
            } catch (Exception e) {
               ...
            }
        }
        return r;
    }
	
	final void Activity::performResume() {
		...
        // mResumed is set by the instrumentation
        mInstrumentation.callActivityOnResume(this);//調用此次啓動Activity的onResume()方法
        ...
    }
	
	  /**
     * Perform calling of an activity's {@link Activity#onResume} method.  The
     * default implementation simply calls through to that method.
     * 
     * @param activity The activity being resumed.
     */
    public void Instrumentation::callActivityOnResume(Activity activity) {
        activity.mResumed = true;
        activity.onResume();//onResume()被調用
        
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    am.match(activity, activity, activity.getIntent());
                }
            }
        }
    }
這裏所分析的當前Activity的啓動過程與我們所知的Activity啓動的生命週期調用順序是吻合的。當前啓動的Activity resume之後,還需要通知AMS:
   final void ActivityThread::handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
			...
            // Tell the activity manager we have resumed.
            if (reallyResume) {
                try {
                    ActivityManagerNative.getDefault().activityResumed(token);//通知Activity已經resumed
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }

        } else {
            ...
        }
    }
即:

    @Override
    public final void AMS::activityResumed(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityResumedLocked(token);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }
	
	final void ActivityStack::activityResumedLocked(IBinder token) {
        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
        if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
        r.icicle = null;
        r.haveState = false;
    }

至此,在新進程中啓動Activity的流程就分析完畢了。我們知道,Activity還可以在已有進程中啓動,這部分流程與上面分析的流程有很大的共同性,最大的不同點就是在判斷當前Activity的進程是否創建部分,如果此時系統檢測到當前Activity需要運行的進程已經存在,則會直接調用ActivityStackSupervisor::realStartActivityLocked()去啓動Activity,而不用在爲Activity創建完進程後再去啓動了。這部分代碼可以參考上述內容中的註釋。


回顧上述的分析流程,我們要對系統啓動Activity所做的一些重要處理格外關注,對其他的一些非核心流程可以適當略過;這樣可以讓我們更深入理解Activity啓動的核心內容。


PS:本篇中只側重分析了Activity的啓動流程及相關生命週期函數的調用時機;其中,AMS中爲Activity創建進程ActivityThread中爲Activity初始化上下文環境、配置資源等內容都略過了,這兩部分內容會在接下來的文章中做分析、記錄。







發佈了72 篇原創文章 · 獲贊 68 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章