通常我們?cè)贏ctivity中啟動(dòng)一個(gè)另一個(gè)Activity钦铁,就是調(diào)用Activity的startActivity方法圣勒,這個(gè)最終會(huì)調(diào)用到Activity的startActivityForResult方法。那你有沒(méi)有想過(guò)Activity的啟動(dòng)到底經(jīng)歷了哪些過(guò)程紊遵,我們今天就來(lái)分析一下蝠检。
在具體分析之前,要先說(shuō)明一下肝箱,Activity的啟動(dòng)流程在細(xì)節(jié)挺繁瑣的,比如啟動(dòng)另一個(gè)App的Activity或者啟動(dòng)不同的launchMode的Activity稀蟋,在細(xì)節(jié)上都會(huì)有不同煌张。我們這次的源碼分析著重分析一下流程,為了簡(jiǎn)單起見(jiàn)退客,就以分析一個(gè)Activity啟動(dòng)app內(nèi)部另一個(gè)standard模式的Activity為主骏融。
Activity啟動(dòng)另一個(gè)Activity之前,當(dāng)前的Activity先要執(zhí)行onPause萌狂,被啟動(dòng)的Activity才會(huì)執(zhí)行到onResume方法档玻。這中間實(shí)際上是會(huì)執(zhí)行4次IPC過(guò)程的:
- 當(dāng)前Activity發(fā)起啟動(dòng)另一個(gè)Activity的請(qǐng)求——>ActivityManagerService
- ActivityManagerService——> 通知App暫停當(dāng)前Activity
- 當(dāng)前App告知已經(jīng)暫停了當(dāng)前的Activity——> ActivityManagerService
- ActivityManagerService ——> 通知App啟動(dòng)新的Activity
注:本次源碼分析采用Android7.0,不同版本的源碼在細(xì)節(jié)上會(huì)有不同茫藏,比如窃肠,在Android8.0上ActivityManagerService就改成了以AIDL的方式來(lái)寫,請(qǐng)不要太糾結(jié)API的不同刷允。
注:本文Activity啟動(dòng)過(guò)程源碼分析過(guò)程比較長(zhǎng)冤留,代碼較繁瑣,請(qǐng)做好心理準(zhǔn)備树灶。
Activity啟動(dòng)涉及到的類
首先要簡(jiǎn)單介紹一下Activity啟動(dòng)過(guò)程涉及到的類纤怒,以便于更好的理解這個(gè)啟動(dòng)過(guò)程。
- ActivityThread:App啟動(dòng)的入口
- ApplicationThread:ActivityThread的內(nèi)部類天通,繼承Binder泊窘,可以進(jìn)程跨進(jìn)程通信。
- ApplicationThreadProxy:ApplicationThread的一個(gè)本地代理像寒,其它的client端通過(guò)這個(gè)對(duì)象調(diào)用server端ApplicationThread中方法烘豹。
- Instrumentation:負(fù)責(zé)發(fā)起Activity的啟動(dòng)、并具體負(fù)責(zé)Activity的創(chuàng)建以及Activity生命周期的回調(diào)诺祸。一個(gè)應(yīng)用進(jìn)程只會(huì)有一個(gè)Instrumentation對(duì)象携悯,App內(nèi)的所有Activity都持有該對(duì)象的引用。
- ActivityManagerService:簡(jiǎn)稱AMS筷笨,是service端對(duì)象憔鬼,負(fù)責(zé)管理系統(tǒng)中所有的Activity
- ActivityManagerProxy:是ActivityManagerService的本地代理
- ActivityStack:Activity在AMS的棧管理,用來(lái)記錄已經(jīng)啟動(dòng)的Activity的先后關(guān)系胃夏,狀態(tài)信息等轴或。通過(guò)ActivityStack決定是否需要啟動(dòng)新的進(jìn)程。
- ActivityRecord:ActivityStack的管理對(duì)象仰禀,每個(gè)Activity在AMS對(duì)應(yīng)一個(gè)ActivityRecord照雁,來(lái)記錄Activity的狀態(tài)以及其他的管理信息。其實(shí)就是服務(wù)器端的Activity對(duì)象的映像答恶。
- TaskRecord:AMS抽象出來(lái)的一個(gè)“任務(wù)”的概念饺蚊,是記錄ActivityRecord的棧萍诱,一個(gè)“Task”包含若干個(gè)ActivityRecord。AMS用TaskRecord確保Activity啟動(dòng)和退出的順序卸勺。
介紹完這些砂沛,我們開(kāi)始進(jìn)入正題
Activity的啟動(dòng)過(guò)程
Activity啟動(dòng)最終會(huì)調(diào)用到startActivityForResult方法,我們只需要關(guān)注mParent == null中的邏輯即可曙求。mParent代表的是ActivityGroup碍庵,其最開(kāi)始是為了在一個(gè)界面中嵌入多個(gè)子Activity,在API13的時(shí)候就已經(jīng)廢棄了悟狱,可以使用Fragment表示一個(gè)界面的多個(gè)區(qū)域静浴。
# android.app.Activity
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
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());
}
...
} else {
...
}
}
調(diào)用了Instrumentation的execStartActivity方法,在這里通過(guò)ActivityManagerNative.getDefault()
方法獲取ActivityManagerService的一個(gè)本地代理對(duì)象ActivityManagerProxy挤渐,然后調(diào)用了其startActivity方法:
# android.app.Instrumentation
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
...
int result = ActivityManagerNative.getDefault()
.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;
}
我們看一下ActivityManagerNative苹享,繼承了Binder并實(shí)現(xiàn)了IActivityManager接口,ActivityManagerService就是繼承了ActivityManagerNative浴麻。
public abstract class ActivityManagerNative extends Binder implements IActivityManager
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback
class ActivityManagerProxy implements IActivityManager
ActivityManagerNative實(shí)際上獲取的就是其內(nèi)部類ActivityManagerProxy對(duì)象得问。ActivityManagerProxy只是ActivityManagerService的本地代理對(duì)象,其startActivity方法會(huì)調(diào)用到AMS的startActivity方法软免。而且要注意宫纬,這個(gè)startActivity方法會(huì)把ApplicationThread對(duì)象傳遞到AMS所在進(jìn)程,當(dāng)然了AMS拿到的實(shí)際上是ApplicationThread的代理對(duì)象ApplicationThreadProxy膏萧,AMS就要通過(guò)這個(gè)代理對(duì)象與我們的App進(jìn)程進(jìn)行通信漓骚。
# android.app.ActivityManagerNative
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;
}
};
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
static public IActivityManager getDefault() {
return gDefault.get();
}
注:在Android8.0,由于使用AIDL的方式來(lái)寫ActivityManagerService榛泛,ActivityManagerNative已經(jīng)過(guò)期蝌蹂。
我們接著看一下AMS的startActivity方法:
# com.android.server.am.ActivityManagerService
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());
}
startActivity方法緊接著調(diào)用了其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);
}
接著調(diào)用了ActivityStarter的startActivityMayWait方法曹锨,由于方法很長(zhǎng)孤个,我們只保留關(guān)鍵的流程部分:
# com.android.server.am.ActivityStarter
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, IActivityManager.WaitResult outResult, Configuration config,
Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
...
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);
...
}
}
ActivityStarter調(diào)用了自身的startActivityLocked方法,這又是一個(gè)很長(zhǎng)的方法艘希,保留關(guān)鍵的流程如下硼身。
# com.android.server.am.ActivityStarter
final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
...
try {
mService.mWindowManager.deferSurfaceLayout();
err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true, options, inTask);
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);
return err;
}
ActivityStarter又調(diào)用了自身的startActivityUnchecked方法,
# com.android.server.am.ActivityStarter
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
...
if (mDoResume) {
...
if (!mTargetStack.isFocusable()
...
} else {
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
...
}
...
return START_SUCCESS;
}
在ActivityStarter中調(diào)用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法覆享。
# com.android.server.am.ActivityStackSupervisor
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
...
}
在ActivityStackSupervisor的resumeFocusedStackTopActivityLocked中又調(diào)用了ActivityStack的resumeTopActivityUncheckedLocked方法。
# com.android.server.am.ActivityStack
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
...
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
ActivityStack在resumeTopActivityUncheckedLocked又調(diào)用了其自身的resumeTopActivityInnerLocked方法营袜。
# com.android.server.am.ActivityStack
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
..
// We need to start pausing the current activity so the top one can be resumed...
...
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
}
...
}
由于當(dāng)前的Activity執(zhí)行了onResume撒顿,所以mResumedActivity != null 條件滿足,就會(huì)調(diào)用startPausingLocked方法先暫停當(dāng)前的Activity荚板。注意:這個(gè)過(guò)程必然是一個(gè)IPC過(guò)程凤壁。我們看一下startPausingLocked方法吩屹。
# com.android.server.am.ActivityStack
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean dontWait) {
ActivityRecord prev = mResumedActivity;
...
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
...
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} catch (Exception e) {
...
}
} else {
...
}
...
}
prev.app.thread表示的是IApplicationThread對(duì)象,在這里就是指的發(fā)起啟動(dòng)的Activity所在進(jìn)程的ApplicationThread的本地代理ApplicationThreadProxy拧抖。調(diào)用它的schedulePauseActivity方法煤搜,很明顯是一次IPC過(guò)程,最終調(diào)用到server端唧席,也就是發(fā)起啟動(dòng)的Activity所在進(jìn)程ApplicationThread的schedulePauseActivity方法擦盾。
# android.app.ActivityThread$$ApplicationThread
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);
}
通過(guò)Hander的轉(zhuǎn)發(fā),接著會(huì)調(diào)用到ActivityThread的handlePauseActivity方法淌哟。
# android.app.ActivityThread
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
ActivityClientRecord r = mActivities.get(token);
...
if (r != null) {
...
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
...
// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
在ActivityThread的handlePauseActivity中迹卢,首先會(huì)調(diào)用performPauseActivity來(lái)暫停當(dāng)前的Activity,經(jīng)過(guò)層層調(diào)用徒仓,會(huì)調(diào)用到Intrumentation的callActivityOnPause方法腐碱,最終調(diào)用Activity的onPause方法,這一塊的流程比較簡(jiǎn)單掉弛,在這里就不再詳細(xì)分析了症见,感興趣的可以自己研究下。
暫停之后殃饿,會(huì)調(diào)動(dòng)ActivityManagerNative.getDefault().activityPaused(token)
谋作,這個(gè)很明顯又是一次IPC過(guò)程,就是告訴AMS壁晒,已經(jīng)暫停當(dāng)前的Activity瓷们,可以啟動(dòng)新的Activity 了。
我們來(lái)看一下AMS的的activityPaused方法:
# com.android.server.am.ActivityManagerService
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
AMS中的activityPaused又調(diào)用了ActivityStack的activityPausedLocked方法秒咐。
# com.android.server.am.ActivityStack
final void activityPausedLocked(IBinder token, boolean timeout) {
...
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)"));
completePauseLocked(true, null);
return;
} else {
...
}
}
...
}
在這個(gè)方法中又調(diào)用了ActivityStack自身的completePauseLocked方法谬晕,
# com.android.server.am.ActivityStack
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
} else {
...
}
}
...
}
然后又調(diào)用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法,這視乎又重新調(diào)用了一遍携取,真復(fù)雜啊攒钳。
這個(gè)流程我們上面講過(guò)了,ActivityStackSupervisor會(huì)繼續(xù)調(diào)用ActivityStack的resumeTopActivityUncheckedLocked方法雷滋,然后ActivityStack又調(diào)用其resumeTopActivityInnerLocked方法不撑,調(diào)來(lái)調(diào)去,又到這個(gè)方法里面了晤斩,上次在這里是執(zhí)行了前一個(gè)Activity的onPause方法焕檬。這次會(huì)調(diào)用到ActivityStackSupersivor的startSpecificActivityLocked方法。
# com.android.server.am.ActivityStack
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// 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) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
}
...
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
...
} else {
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
分析到這里澳泵,好像我們的就要開(kāi)始啟動(dòng)我們的目標(biāo)Activity了实愚,好激動(dòng)有木有!
在ActivityStackSupersivor的startSpecificActivityLocked方法中會(huì)判斷Activity所在進(jìn)程是否存在,如果不存在的話就要?jiǎng)?chuàng)建一個(gè)新的進(jìn)程腊敲。在這里击喂,我們是Activity啟動(dòng)其App內(nèi)部的另一個(gè)Activity,所以進(jìn)程肯定是存在的碰辅,會(huì)走到realStartActivityLocked方法中懂昂。
# com.android.server.am.ActivityStackSupervisor
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
...
if (app != null && app.thread != null) {
try {
...
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
...
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
再來(lái)看一下ActivityStackSupersivor的realStartActivityLocked方法,這次似乎真的要啟動(dòng)一個(gè)Activity了没宾。
# com.android.server.am.ActivityStackSupervisor
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
...
try {
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);
...
} catch (RemoteException e) {
...
}
...
return true;
}
看了代碼凌彬,果然,調(diào)用了app.thread.scheduleLaunchActivity方法榕吼,app.thread我們前面講過(guò)饿序,就是IApplicationThread對(duì)象,實(shí)際上就是ApplicationThreadProxy對(duì)象羹蚣,經(jīng)過(guò)IPC過(guò)程會(huì)調(diào)用到ApplicationThread的scheduleLaunchActivity方法原探,我們來(lái)看一下:
# android.app.ActivityThread$$ApplicationThread
@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) {
...
sendMessage(H.LAUNCH_ACTIVITY, r);
}
通過(guò)Hander的轉(zhuǎn)發(fā),接著會(huì)調(diào)用到ActivityThread的handlePauseActivity方法顽素。
# android.app.ActivityThread
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
...
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
...
} else {
...
}
}
handlePauseActivity內(nèi)部調(diào)用performLaunchActivity方法:
# android.app.ActivityThread
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
...
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.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
return activity;
}
在performLaunchActivity內(nèi)部咽弦,創(chuàng)建了Activity對(duì)象,并調(diào)用了activity的attach方法胁出,在這個(gè)方法中綁定一些屬性型型,并且創(chuàng)建了Activity所屬的Window對(duì)象。接著Instrumentation會(huì)調(diào)用callActivityOnCreate全蝶、callActivityOnRestoreInstanceState闹蒜、callActivityOnPostCreate等來(lái)完成Activity生命周期的回調(diào)。不過(guò)有一點(diǎn)很有意思抑淫,在這個(gè)方法中Activity自己調(diào)用了其performStart方法绷落,但這個(gè)方法內(nèi)部又調(diào)用了Instrumentation的callActivityOnStart方法,進(jìn)而又調(diào)用了Activity的onStart方法始苇。繞過(guò)來(lái)繞過(guò)去砌烁,總之,Activity生命周期方法的調(diào)用均是通過(guò)Instrumentation來(lái)控制的催式。
至此函喉,Activity的啟動(dòng)過(guò)程算是分析完了,太費(fèi)腦筋了荣月,需要來(lái)一瓶營(yíng)養(yǎng)快線補(bǔ)補(bǔ)身體管呵。流程太多,不好記哺窄,但是有句話說(shuō)的好 "一圖勝千言"撇寞,下面我們來(lái)看一下Activity啟動(dòng)的一個(gè)時(shí)序圖顿天。
總結(jié)
源碼分析過(guò)程是比較繞堂氯,比較燒腦的過(guò)程蔑担,不要太糾結(jié)去API的調(diào)用,盡量側(cè)重流程咽白。分析源碼啤握,最好帶著問(wèn)題去分析,不要為了分析而分析晶框,盡量在分析過(guò)程中尋找自己想要的答案排抬。比如:
- Activity對(duì)象是怎么創(chuàng)建的?
- Window對(duì)象是什么時(shí)候創(chuàng)建的授段?
- LayoutInflater什么時(shí)候創(chuàng)建的蹲蒲?
- 為什么在Activity中的布局中或者Fragment的中View獲取的Context都是其所在的Activity對(duì)象?
- 為什么自定義View一定要有兩個(gè)參數(shù)的構(gòu)造函數(shù)侵贵?
- Activity的生命周期方法是被誰(shuí)回調(diào)的届搁?
- Application是什么時(shí)候創(chuàng)建的?
- ClassLoader對(duì)象是什么時(shí)候創(chuàng)建的窍育?
- 子線程可以啟動(dòng)Activity卡睦、Service嗎?
- 下拉通知欄漱抓,會(huì)影響Activity生命周期嗎表锻?
筆者初入Android開(kāi)發(fā)沒(méi)多久的時(shí)候,有次面試乞娄,面試官問(wèn)我在子線程中啟動(dòng)Activity可以嗎瞬逊?我回答可以,因?yàn)槲以囘^(guò)仪或,但是問(wèn)我為什么我卻不知道确镊。如果那時(shí)候看了Activity啟動(dòng)過(guò)程的源碼,看了Binder機(jī)制的話溶其,應(yīng)該很容易的就回答出來(lái)了骚腥。