說明:本文是基于Android6.0源碼來分析的
??本文只是從源碼的角度分析Activity的啟動(dòng)流程,并不會(huì)介紹Activity本身的一些特點(diǎn)涯塔,比如如何創(chuàng)建Activity鹤啡,如何開啟一個(gè)新的Activity惯驼,Activty的生命周期,啟動(dòng)模式等;如果你是一個(gè)剛?cè)腴T的Android開發(fā)祟牲,這篇文章可能對(duì)你來說有些晦澀難懂隙畜,如果你是一個(gè)老猿并且想對(duì)Activity的啟動(dòng)流程又一個(gè)比較直觀的了解,這片文章或許能夠幫助你说贝。
??由于Activity的啟動(dòng)會(huì)根據(jù)不同的狀態(tài)议惰,不同的啟動(dòng)模式,是否在一個(gè)應(yīng)用內(nèi)部啟動(dòng)一個(gè)Activity等不同情況而不同乡恕,如果都考慮進(jìn)來可能會(huì)比較繁瑣言询,不利于掌握和分析,所以我們就以一個(gè)Activty的啟動(dòng)模式是standard的標(biāo)準(zhǔn)模式并且是在同一個(gè)應(yīng)用里面且不帶Bundle參數(shù)的情況下來分析傲宜,下面我們就正式進(jìn)入分析的流程运杭。
??一般我們開啟一個(gè)Activity都是從startActivity方法開始的
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
接著接著調(diào)用Activity中的帶兩個(gè)參數(shù)的startActivity方法
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
option是null,所有會(huì)走else里的邏輯
public void startActivityForResult(Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
首次開啟mParent == null函卒,所以走if里面的邏輯辆憔,由于startActivityForResult的代碼有點(diǎn)多,所以我只貼我們關(guān)注的部分代碼
public void startActivityForResult(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());
}
...
}
}
如果想了解Instrumentation這個(gè)類报嵌,可以看一下這片文章Instrumentation的介紹虱咧;Now接著我們的Activity的啟動(dòng)流程繼續(xù)分析,調(diào)用Instrumentation#execStartActivity
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
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);
}
...
}
我們看到是通過 ActivityManagerNative.getDefault()來啟動(dòng)的锚国,那么getDefault()是什么呢腕巡?
static public IActivityManager getDefault() {
return gDefault.get();
}
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;
}
};
其實(shí)就是在獲取ActivityManagerServer。
IActivityManager是個(gè)接口血筑,ActivityManagerNative是一個(gè)IActivityManager是接口的一個(gè)抽象實(shí)現(xiàn)類绘沉,ActivityManagerService又是ActivityManagerNative的一個(gè)具體的實(shí)現(xiàn)類。所以最終調(diào)用的是云挟,ActivityManagerService#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 options) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, options,
UserHandle.getCallingUserId());
}
@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) {
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
}
就是不斷的調(diào)用ActivityManagerService的重載方法,然后再調(diào)用ActivityStackSupervisor#startActivityMayWait方法园欣。
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, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
...
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, voiceInteractor, resultTo, resultWho,
requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
componentSpecified, null, container, inTask);
...
}
然后又調(diào)用了重載的startActivityLocked()帖世,這個(gè)方法真的是和老太太的腳一樣,又臭又長(zhǎng)啊沸枯,但是重點(diǎn)就在這個(gè)方法最后面
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 ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
ActivityContainer container, TaskRecord inTask) {
...
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
...
}
結(jié)合調(diào)用了startActivityUncheckedLocked()日矫,這個(gè)方法其實(shí)也不簡(jiǎn)單,也是很長(zhǎng)绑榴,邏輯很多,但是重要的方法也是在最后幾行調(diào)用的哪轿。
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask) {
...
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
...
}
接著調(diào)用了ActivityStack#startActivityLocked方法,怎么說呢,這個(gè)方法也會(huì)比較長(zhǎng)的翔怎,但是相較于前面的兩個(gè)方法窃诉,這個(gè)方法還是比較端的杨耙,我們只貼關(guān)鍵代碼
final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
...
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
...
}
接著調(diào)用了ActivityStack#resumeTopActivitiesLocked方法
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
...
if (!addingToTask && reuseTask == null) {
// We didn't do anything... but it was needed (a.k.a., client
// don't use that intent!) And for paranoia, make
// sure we have correctly resumed the top activity.
//重點(diǎn)方法
if (doResume) {
targetStack.resumeTopActivityLocked(null, options);
if (!movedToFront) {
// Make sure to notify Keyguard as well if we are not running an app
// transition later.
notifyActivityDrawnForKeyguard();
}
} else {
ActivityOptions.abort(options);
}
return ActivityManager.START_TASK_TO_FRONT;
}
...
}
接著調(diào)用了ActivityStack#resumeTopActivityLocked方法
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle 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);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
接著調(diào)用resumeTopActivityInnerLocked方法,這個(gè)方法也很長(zhǎng)飘痛。
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
...
}
接著調(diào)用ActivityStackSupervisor#startSpecificActivityLocked方法,這個(gè)方法還是比較重要的珊膜,里面有行代碼還是很重要的,那就是 mService.startProcessLocked方法宣脉,這個(gè)方法就是開啟一個(gè)新app的時(shí)候創(chuàng)建新進(jìn)程的方法车柠,這個(gè)不展開了,后面會(huì)寫一片Android應(yīng)用的啟動(dòng)流程塑猖,就會(huì)設(shè)計(jì)到這里了竹祷。
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
...
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);
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);
...
}
這里調(diào)用的就是ActivityStackSupervisor#realStartActivityLocked方法,這個(gè)方法也很長(zhǎng)羊苟,我們只關(guān)注重點(diǎn)的方法塑陵,不然就會(huì)陷入只見樹木,不見森林的尷尬境地蜡励。
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
...
// switch back to it faster and look better.
if (isFrontStack(stack)) {
mService.startSetupActivityLocked();
}
...
}
接著掉了ActivityManagerService#startSetupActivityLocked
void startSetupActivityLocked() {
...
mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
null, null, null);
...
}
接著又回調(diào)到了ActivityStackSupervisor#startActivityLocked方法,haha這個(gè)方法也很長(zhǎng)猿妈,不過別慌,我們還是老規(guī)矩巍虫,只貼重點(diǎn)方法
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 ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
ActivityContainer container, TaskRecord inTask) {
...
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
...
}
然后是掉了ActivityStackSupervisor#startActivityUncheckedLocked,方法很長(zhǎng)鳍刷,我們也只看重點(diǎn)
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask) {
...
targetStack.startActivityLocked(r, newTask, doResume, keepCurTranstion, options);
...
}
然后掉了ActivityStack#startActivityLocked方法
final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
...
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
...
}
然后ActivityStackSupervisor#resumeTopActivitiesLocked方法
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
//這個(gè)地方要注意占遥,調(diào)用的不是循環(huán)里面的resumeTopActivityLocked方法。
...
if (isFrontStack(targetStack)) {
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
...
}
然后就是ActivityStack#resumeTopActivityLocked方法
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle 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);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
...
result = resumeTopActivityInnerLocked(prev, options);
...
}
//這個(gè)方法也很長(zhǎng)输瓜,只貼重點(diǎn)方法
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
...
}
接著回到ActivityStackSupervisor#startSpecificActivityLocked
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
...
realStartActivityLocked(r, app, andResume, checkConfig);
...
}
走了這么多不瓦胎,而realStartActivityLocked方法就是真正的去開啟一個(gè)Activity的方法。
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, new Configuration(mService.mConfiguration),
new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
...
}
app.thread其實(shí)就是ApplicationThread尤揣,所以最后調(diào)用的其實(shí)就是ApplicationThread#scheduleLaunchActivity
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);
...
}
最終發(fā)送handler消息給H
public void handleMessage(Message msg) {
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);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break;
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity a = performLaunchActivity(r, customIntent);
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
...
}
//順便再提一嘴搔啊,activity的布局繪制其實(shí)就在handleResumeActivity方法倆面的這一行代碼開始的
wm.addView(decor, l);
接著看handleLaunchActivity方法
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//這里就是創(chuàng)建activity的實(shí)例,可以看出是通過反射創(chuàng)建的
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);
}
}
try {
//這部分是創(chuàng)建應(yīng)用的application的地方北戏,
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
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);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
//這里就是通過Instrumentation去調(diào)用activity的onCreate方法的地方负芋, mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
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) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
...
}
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
//如果application存在直接返回,這里可以確定一個(gè)app只有一個(gè)application了
if (mApplication != null) {
return mApplication;
}
...
}
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
//Here we go,真正的去執(zhí)行activity的onCreate的地方
activity.performCreate(icicle);
postPerformCreate(activity);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
restoreHasCurrentPermissionRequest(icicle);
/真正的onCreate的方法執(zhí)行的地方嗜愈。
onCreate(icicle, persistentState);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
上面這部分的代碼估計(jì)能解決你對(duì)activity的大部分疑問旧蛾,
里買呢又創(chuàng)建activity的過程,onCreate方法的調(diào)用等蠕嫁,具體邏輯在上面的代碼中已經(jīng)寫處理啊了锨天。
到這里Acvitiy的啟動(dòng)流程我們就介紹完了,下面我會(huì)把Activity的啟動(dòng)流程圖貼出來剃毒,相對(duì)干巴巴的代碼病袄,我們可能會(huì)覺得流程圖更清晰一些搂赋,就像會(huì)說話的人,眼睛看到那里他好像就能告訴我們?cè)诹鞒痰氖裁吹胤搅艘娌蝗绻覀冊(cè)诳创a邏輯的時(shí)候覺得思緒很亂脑奠,往往流程圖能更清晰的從全局去理解和掌握代碼的執(zhí)行流程,如果分析的那些地方有錯(cuò)誤不正確還請(qǐng)指出左刽,謝謝捺信。
-
流程圖
-
流程圖地址,流程圖是用在線的ProcessOn軟件做的欠痴。
-
流程圖地址,流程圖是用在線的ProcessOn軟件做的欠痴。