深刻理解Android-Activity的啓動過程

1、準備工做

一、準備好閱讀源碼的工具。html

二、主要類的功能介紹java

  • ActivityManagerServices 簡稱AMS,服務端對象,是Android中最核心的服務,主要負責系統中四大組件的啓動、切換和調度及應用進程的管理和調度工做。負責系統中全部Activity的生命週期.(深刻理解Android 卷II 對此有進行深刻的講解 http://wiki.jikexueyuan.com/project/deep-android-v2/activity.html)。
  • ActivityThread ,APP的真正入口。當開啓APP後,會調用main()開始運行,開啓消息循環隊列,這就是傳說中的UI或者叫主線程,與AMS配合使用,一塊兒完成Activity 的管理工做。
  • Instrumentation ,每個應用程序只有一個Instrumentation對象,每一個activity內都有一個對該對象的引用。Instrumentation能夠理解爲應用進程的管家,ActivityThread要建立和暫停某個activity時,都須要經過Instrumentation來進行具體的操做。
  • ApplicationThread 用來實現AMS 與 ActivityThread 之間的交互。在AMS須要管理相關Application中的Activity的生命週期時,經過ApplicationThread的代理對象與ActivityThread通信。
  • ApplicationThreadProxy,是ApplicationThread在服務端的代理,負責和客戶端的ApplicationThread通信。AMS就是經過該代理與ActivityThread通信的。
  • ActivityStack,Activity在AMS的棧管理,用來記錄已經啓動的Activity的前後關係,狀態信息等。經過ActivityStack決定是否須要啓動新的進程。
  • ActivityRecord,ActivityStack的管理對象,每一個Activity在AMS對應一個ActivityRecord,來記錄Activity的狀態以及其餘的管理信息。其實就是服務器端的Activity對象的映像。
  • TaskRecord,AMS抽象出來的一個「任務」的概念,是記錄ActivityRecord的棧,一個「Task」包含若干個ActivityRecord。AMS用TaskRecord確保Activity啓動和退出的順序。若是你清楚Activity的4種launchMode,那麼對這個概念應該不陌生。

2、啓動過程分析

咱們從源碼的package android.app.Activity.java 的 startActivity 方法分析,其中 startActivity 方法有幾種重載方式:android

@Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }
   @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }

兩個重載方法,都調用了 startActivityForResult 方法,代碼以下:設計模式

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {
if (mParent == null) { // mParent 表示這 當如今的Activity 沒有父Activity
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} 

....  ignore some code ...

}

在前面說過Instrumentation這個類,每一個Activity都持有一個Instrumentation對象的一個引用,當時整個進程中只會存在一個Instrumentation對象,當startActivityForResult方法調用後實際仍是調用了mInstrumentation.execStartActivity,mInstrumentation 在Activity的attach方法中初始化。服務器

這裏注意 mMainThread 是 ActivityThread 也就是咱們常說的主線程,mMainThread.getApplicationThread() ApplicationThread 是ActivityThread 的內部類。app

當 mParent != null 時走下面這段代碼:async

else { if (options != null) { //當如今的Activity有父Activity的時候會調用,可是在startActivityFromChild()內部實際仍是調用的mInstrumentation.execStartActivity() mParent.startActivityFromChild(this, intent, requestCode, options); } else { mParent.startActivityFromChild(this, intent, requestCode); } }

Instrumentation 的 execStartActivity 方法,代碼實現以下:ide

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

因此,當咱們程序調用startActivity方法的時候,其實是調用的Instrumentation 的相關方法。函數

Instrumentation 能夠意爲‘儀器’,咱們看一下這個類大體包含哪些方法工具

[圖片上傳失敗...(image-118e35-1522472148194)]

這個類裏面的方法大多數和Application和Activity 有關,這個類就是完成了對Application和Activity的初始化和生命週期的工具類,好比咱們看一下callActivityOnCreate方法,代碼以下:

/**
* Perform calling of an activity's {@link Activity#onCreate} 注意這一句話,調用了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 callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}

再看一下activity.performCreate(icicle);方法

final void performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}

Instrumentation 這個類是很重要的,對Activity的生命週期方法調用根本離不開他,這麼重要的類,爲何在開發中沒有發現他的軌跡呢?

Instrumentation 能夠說是一個大管家,管內無論外,他是老闆娘。

老闆是誰呢?固然是 ActivityThread .

AMS說:「ActivityThread,你給我暫停一個Activity!」

ActivityThread就說:「沒問題!」而後轉身和Instrumentation說:「老婆,AMS讓暫停一個Activity,我這裏忙着呢,你快去幫我把這事辦了把~」

因而,Instrumentation就去把事兒搞定了。

因此說,AMS是董事會,負責指揮和調度的,ActivityThread是老闆,雖說家裏的事本身說了算,可是須要遵從AMS的指揮,而Instrumentation則是老闆娘,負責家裏的大事小事,可是通常不拋頭露面,聽一家之主ActivityThread的安排。

咱們繼續分析 execStartActivity方法,根據這段代碼能夠看出,啓動Activity 是由 ActivityManager.getService().startActivity 方法啓動的,這裏注意API 26 及26 以後源碼有變更。

int result = ActivityManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);

ActivityManager.getService() 的代碼以下:

/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b); // 如何實現的呢?
return am;
}
};

IActivityManager.Stub.asInterface(b); 這句代碼我找了很久終於在 ActivityManagerNative 類中找到了 代碼以下:

public abstract class ActivityManagerNative {
/**
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*
* @deprecated use IActivityManager.Stub.asInterface instead. // 最重要的是這句話   改成使用IActivityManager.Stub.asInterface
*/

static public IActivityManager asInterface(IBinder obj) {
return IActivityManager.Stub.asInterface(obj);
}

static public IActivityManager getDefault() {
return ActivityManager.getService();
}
}

咱們在看一下 API 26 以前的ActivityManagerNative源碼是如何寫的呢?代碼以下:

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    /**
     *  //最終返回的仍是一個ActivityManagerProxy對象
     */
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

//這裏面的Binder類型的obj參數會做爲ActivityManagerProxy的成員變量保存爲mRemote成員變量,負責進行IPC通訊
        return new ActivityManagerProxy(obj);
    }

    /**
     *  //從類聲明上,咱們能夠看到ActivityManagerNative是Binder的一個子類,並且實現了IActivityManager接口
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }
//經過單例模式獲取一個IActivityManager對象,這個對象經過asInterface(b)得到 
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>()
{
protected IActivityManager create()
{
IBinder b = ServiceManager.getService("activity"); 
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b); 
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
}
...ignore some code ...
}

搜得死內 ,asInterface 方法返回的就是ActivityManagerService的遠程接口,即ActivityManagerProxy。

咱們再看一下 ActivityManagerProxy 方法中的 startActivity() 方法,這裏面主要作的事情就是IPC通訊,利用 Binder 對象,調用transact(),把全部須要的參數封裝成 Parcel對象,向AMS發送數據通訊,代碼以下:

public int 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;
    }

private IBinder mRemote;
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);

Binder本質上只是一種底層通訊方式,和具體服務沒有關係。爲了提供具體服務,Server必須提供一套接口函數以便Client經過遠程訪問使用各類服務。這時一般採用Proxy設計模式:將接口函數定義在一個抽象類中,Server和Client都會以該抽象類爲基類實現全部接口函數,所不一樣的是Server端是真正的功能實現,而Client端是對這些函數遠程調用請求的包裝。

具體的流程是這樣的: 客戶端:ActivityManagerProxy =====>Binder驅動=====> ActivityManagerService:服務器

可是!這裏Binder通訊是單方向的,即從ActivityManagerProxy指向ActivityManagerService的,若是AMS想要通知ActivityThread作一些事情,應該咋辦呢?

仍是經過Binder通訊,不過是換了另一對,換成了ApplicationThread和ApplicationThreadProxy。

客戶端:ApplicationThread <=====Binder驅動<===== ApplicationThreadProxy:服務器

能夠看出不論是API 26 仍是 API 26 以前的 ,主要作的事情就是IPC通訊,利用 Binder 對象,向AMS發送數據通訊。

實際上就是調用了AMS 中的startActivity方法。

public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback

API 26 AMS 的繼承關係也發生了改變

public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback

兩種一對比其實實現都是同樣的邏輯。

AMS接收到客戶端的請求以後,會如何開啓一個Activity?

OK,當咱們點擊桌面圖標調用startActivity,終於把數據和要開啓的Activity的請求發送到了AMS,那麼AMS到底作了什麼呢?

注意!這一塊調用的方法鏈很是之多,若是頭腦不夠清晰建議休息一下。

AMS收到startActivity的請求以後,會按照以下的方法鏈進行調用

調用startActivity()

@Override

public final int startActivity(IApplicationThread caller, String callingPackage,

Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,

int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {

return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,

resultWho, requestCode, startFlags, profilerInfo, bOptions,

UserHandle.getCallingUserId());

}

調用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 options, int userId) {

...ignore some code...

return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,

resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,

profilerInfo, null, null, options, userId, null, null);

}

在這裏又出現了一個新對象ActivityStackSupervisor,經過這個類能夠實現對ActivityStack的部分操做。

final int startActivityMayWait(IApplicationThread caller, int callingUid,

String callingPackage, Intent intent, String resolvedType,

IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,

IBinder resultTo, String resultWho, int requestCode, int startFlags,

ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,

Bundle options, int userId, IActivityContainer iContainer, TaskRecord inTask) {

...ignore some code...

int res = startActivityLocked(caller, intent, resolvedType, aInfo,

voiceSession, voiceInteractor, resultTo, resultWho,

requestCode, callingPid, callingUid, callingPackage,

realCallingPid, realCallingUid, startFlags, options,

componentSpecified, null, container, inTask);

...ignore some code...

}

繼續調用startActivityLocked()

final int startActivityLocked(IApplicationThread caller,

Intent intent, String resolvedType, ActivityInfo aInfo,

IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,

IBinder resultTo, String resultWho, int requestCode,

int callingPid, int callingUid, String callingPackage,

int realCallingPid, int realCallingUid, int startFlags, Bundle options,

boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,

TaskRecord inTask) {

err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,

startFlags, true, options, inTask);

if (err < 0) {

notifyActivityDrawnForKeyguard();

}

return err;

}

調用startActivityUncheckedLocked(),此時要啓動的Activity已經經過檢驗,被認爲是一個正當的啓動請求。

終於,在這裏調用到了ActivityStack的startActivityLocked(ActivityRecord r, boolean newTask,boolean doResume, boolean keepCurTransition, Bundle options)。

ActivityRecord表明的就是要開啓的Activity對象,裏面分裝了不少信息,好比所在的ActivityTask等,若是這是首次打開應用,那麼這個Activity會被放到ActivityTask的棧頂,

final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,

IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,

boolean doResume, Bundle options, TaskRecord inTask) {

...ignore some code...

targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);

...ignore some code...

return ActivityManager.START_SUCCESS;

}

調用的是ActivityStack.startActivityLocked()

final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
//ActivityRecord中存儲的TaskRecord信息
TaskRecord rTask = r.task;

...ignore some code...

//若是不是在新的ActivityTask(也就是TaskRecord)中的話,就找出要運行在的TaskRecord對象
TaskRecord task = null;
if (!newTask) {
boolean startIt = true;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
task = mTaskHistory.get(taskNdx);
if (task.getTopActivity() == null) {
// task中的全部Activity都結束了
continue;
}

if (task == r.task) {
// 找到了
if (!startIt) {
task.addActivityToTop(r);
r.putInHistory();
mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
r.userId, r.info.configChanges, task.voiceSession != null,
r.mLaunchTaskBehind);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
ActivityOptions.abort(options);
return;
}
break;
} else if (task.numFullscreen > 0) {
startIt = false;
}
}
}

...ignore some code...

// Place a new activity at top of stack, so it is next to interact
// with the user.
task = r.task;
task.addActivityToTop(r);
task.setFrontOfTask();
...ignore some code...
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
}

從ActivityStackSupervisor到ActivityStack,又調回ActivityStackSupervisor,!!!!!!!!!!!!!!!!!

淡定…淡定…我知道你也在內心罵娘,世界如此美妙,你卻如此暴躁,這樣很差,很差…

繼續,剛纔說到哪裏了?我們一塊兒看下StackSupervisor.resumeTopActivitiesLocked(this, r, options)

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
if (targetStack == null) {
targetStack = getFocusedStack();
}
// Do targetStack first.
boolean result = false;
if (isFrontStack(targetStack)) {
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}

...ignore some code...

return result;
}

又調回ActivityStack去了…

ActivityStack.resumeTopActivityLocked()

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
if (inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
inResumeTopActivity = false;
}
return result;
}

我們堅持住,看一下ActivityStack.resumeTopActivityInnerLocked()到底進行了什麼操做

final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {

...ignore some code...

//找出還沒結束的首個ActivityRecord
ActivityRecord next = topRunningActivityLocked(null);
//若是一個沒結束的Activity都沒有,就開啓Launcher程序
if (next == null) {
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
// Only resume home if on home display
final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
return isOnHomeDisplay() &&mStackSupervisor.resumeHomeStackTask(returnTaskType, prev);
}

//先須要暫停當前的Activity。由於咱們是在Lancher中啓動mainActivity,因此當前mResumedActivity!=null,調用startPausingLocked()使得Launcher進入Pausing狀態
if (mResumedActivity != null) {
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
}
}

在這個方法裏,prev.app爲記錄啓動Lancher進程的ProcessRecord,prev.app.thread爲Lancher進程的遠程調用接口IApplicationThead,因此能夠調用prev.app.thread.schedulePauseActivity,到Lancher進程暫停指定Activity。

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
boolean dontWait) {
if (mPausingActivity != null) {
completePauseLocked(false);
}

...ignore some code...

if (prev.app != null && prev.app.thread != null)
try {
mService.updateUsageStats(prev, false);
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} catch (Exception e) {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
...ignore some code...
}

在Lancher進程中消息傳遞,調用ActivityThread.handlePauseActivity(),最終調用ActivityThread.performPauseActivity()暫停指定Activity。接着經過前面所說的Binder通訊,通知AMS已經完成暫停的操做。

ActivityManagerNative.getDefault().activityPaused(token).

上面這些調用過程很是複雜,源碼中各類條件判斷讓人眼花繚亂,因此說若是你沒記住也不要緊,你只要記住這個流程,理解了Android在控制Activity生命週期時是如何操做,以及是經過哪幾個關鍵的類進行操做的就能夠了,之後遇到相關的問題之道從哪塊下手便可,這些過程我雖然也是擼了一遍,但仍是記不清。

image.png

須要注意的代碼 app.thread.scheduleLaunchActivity 這個方法

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

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global and
// override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);.
..................

}

app.thread 實際上就是ApplicationThread,最終回到了ApplicationThread 的scheduleLaunchActivity 方法 來啓動Activity,咱們知道ApplicationThread 是ActivityThread 的內部類

private class ApplicationThread extends IApplicationThread.Stub {
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
}

scheduleLaunchActivity 實現方法很簡單 發送了一個啓動Activity的消息交給Handler處理。

sendMessage 代碼以下:

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

接下來看一下 Handler H 對消息的處理

public void 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;

}

能夠看出Activity的啓動過程由 ActivityThread handleLaunchActivity 方法實現的,看一下 handleLaunchActivity 的代碼以下:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

// If we are getting ready to gc after going to the background, well

// we are back active so skip it.

unscheduleGcIdler();

mSomeActivitiesChanged = true;

if (r.profilerInfo != null) {

mProfiler.setProfiler(r.profilerInfo);

mProfiler.startProfiling();

}

// Make sure we are running with the most recent config.

handleConfigurationChanged(null, null);

if (localLOGV) Slog.v(

TAG, "Handling launch of " + r);

// Initialize before creating the activity

WindowManagerGlobal.initialize();

Activity a = performLaunchActivity(r, customIntent);

if (a != null) {

r.createdConfig = new Configuration(mConfiguration);

reportSizeConfigurations(r);

Bundle oldState = r.state;

handleResumeActivity(r.token, false, r.isForward,

!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

if (!r.activity.mFinished && r.startsNotResumed) {

performPauseActivityIfNeeded(r, reason);

if (r.isPreHoneycomb()) {

r.state = oldState;

}

}

} else {

// If there was an error, for any reason, tell the activity manager to stop us.

try {

ActivityManager.getService()

.finishActivity(r.token, Activity.RESULT_CANCELED, null,

Activity.DONT_FINISH_TASK_WITH_ACTIVITY);

} catch (RemoteException ex) {

throw ex.rethrowFromSystemServer();

}

}

}

從上面代碼能夠看出,performLaunchActivity 方法最終完成了Activity對象的建立和啓動過程,而且經過handleLaunchActivity 方法的handleResumeActivity 調用被啓動Activity的onResume 這一個生命週期方法。

簡單看一下 performLaunchActivity 的代碼,作了些什麼:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//1 從ActivityClientRecord 中獲取待啓動 Activity的組件信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}

// 2 經過Instrumentation的newActivity 方法使用類加載器建立Activity對象
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}

//3 經過LoadedApk 的 makeApplication 方法來嘗試建立 Application 對象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);

...........................

appContext.setOuterContext(activity);
// 4 建立ContextImpl 對象並經過Activity的attach方法來完成一些重要數據的初始化
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);

.........................

// 5 調用Activity的生命週期方法
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}

..................................

return activity;
}

至此,整個Activity的啓動過程完成。

相關文章
相關標籤/搜索