前言
Activity可以算得上是Android開發(fā)中接觸最早和最多的一個類了首尼,簡單的使用相信大家都很熟悉了,本文主要分析一下Activity的啟動流程,有助于加深我們對于Android知識體系的理解持舆,拓寬我們的視野板驳。
源碼分析
首先強調(diào)一下又跛,本文的分析基于Android 9.0(API Level 28)的源碼,不同版本的源碼可能有些不同若治,大體流程還是差不多的慨蓝。閱讀源碼沒什么可說的,只能一步一步去跟代碼端幼,下面我們就直接開始吧礼烈。
通常我們在啟動一個Activity時只需要調(diào)用如下代碼即可:
Intent intent = new Intent(this, XXActivity.class);
startActivity(intent);
從Activity的startActivity(intent)
方法入手,方法的調(diào)用鏈如下:
@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 {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
可以看出startActivity(intent)
方法最終會走到startActivityForResult(Intent intent, int requestCode,Bundle options)
方法婆跑,也省去了我們再去分析startActivityForResult()
方法此熬。
Activity的startActivityForResult方法
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);
// ...
} else {
// ...
}
}
這里我們只需要關(guān)注mParent == null
這部分的邏輯,這里的核心代碼是調(diào)用mInstrumentation.execStartActivity()
方法。mInstrumentation的類型是Instrumentation犀忱,它會在應(yīng)用程序的任何代碼運行之前被實例化募谎,能夠允許你監(jiān)視應(yīng)用程序和系統(tǒng)的所有交互,Application和Activity的創(chuàng)建以及生命周期都會經(jīng)過這個對象去執(zhí)行阴汇。mMainThread的類型是ActivityThread数冬,應(yīng)用程序的入口就是該類中的main()
方法,在該方法中會創(chuàng)建主線程Looper搀庶,開啟消息循環(huán)拐纱,處理任務(wù)。通過mMainThread.getApplicationThread()
方法獲取到的是一個ApplicationThread對象哥倔,它是ActivityThread的內(nèi)部類秸架,它的定義如下:
private class ApplicationThread extends IApplicationThread.Stub{
// ...
}
可以看出它繼承自IApplicationThread.Stub,如果了解一點Binder的話從名稱就能知道IApplicationThread繼承自IInterface接口未斑,內(nèi)部定義了一些業(yè)務(wù)方法咕宿,IApplicationThread.Stub則是一個Binder對象。接下來我們來看一下Instrumentation的execStartActivity()
方法蜡秽。
Instrumentation的execStartActivity方法
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// 將contextThread轉(zhuǎn)為IApplicationThread
// 這里的contextThread是一個ApplicationThread對象府阀,實現(xiàn)了IApplicationThread接口,因此可以這樣轉(zhuǎn)換
IApplicationThread whoThread = (IApplicationThread) contextThread;
// ...
try {
// ...
// 核心代碼
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
// 檢查Activity啟動結(jié)果
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
這里的核心代碼是ActivityManager.getService().startActivity()
芽突,ActivityManager.getService()
方法獲取到的是一個ActivityManagerService對象试浙,簡稱AMS,為了簡便寞蚌,下文也都將其統(tǒng)稱為“AMS”诡延。AMS可就厲害了檐迟,它是Android中的核心服務(wù)杉女,負責調(diào)度各應(yīng)用的進程垢啼,管理四大組件。AMS是一個Binder艘刚,實現(xiàn)了IActivityManager接口管宵,因此應(yīng)用進程能通過Binder機制調(diào)用系統(tǒng)服務(wù)。
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
// 獲取服務(wù)Binder
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// 獲取AMS實例對象
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
值得一提的是ServiceManager管理著所有的系統(tǒng)服務(wù)攀甚,可以將其類比于DNS域名服務(wù)器箩朴,通過服務(wù)名稱可以從ServiceManager中獲取到相應(yīng)的服務(wù)Binder對象。checkStartActivityResult()
方法的作用是檢查Activity的啟動結(jié)果秋度,參數(shù)傳入了startActivity()
方法的返回值炸庞,根據(jù)返回值判斷Activity是否啟動成功,如果啟動失敗會拋出異常荚斯,常見的Unable to find explicit activity class; have you declared this activity in your AndroidManifest.xml異常就是這里拋出的埠居。
接下來我們來看AMS對象的startActivity()
方法:
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 bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
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 bOptions, int userId) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivity");
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
可以看出AMS的startActivity()
方法最終會走到startActivityAsUser()
方法中查牌,方法內(nèi)部是一個挺長的鏈式調(diào)用,第一行的mActivityStartController.obtainStarter()
返回的是一個ActivityStarter對象拐格,之后的一系列調(diào)用可以看做是對ActivityStarter的配置僧免,我們直接來看最后調(diào)用的execute()
方法。
ActivityStarter的execute方法
int execute() {
try {
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
}
} finally {
onExecutionComplete();
}
}
這里有一個判斷捏浊,我們可以不用去了解它的意義,直接來看startActivityMayWait()
方法:
private int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup) {
// ...
// 調(diào)用startActivity方法
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup);
// ...
return res;
}
這里省略了大量代碼撞叨,可以看到startActivityMayWait()
方法最終也是調(diào)用了startActivity()
方法金踪,因此我們不需要搞清楚上面判斷的意義,因為最終執(zhí)行的方法是一樣的牵敷。接下來來看ActivityStarter的startActivity()
方法:
// 1
private int startActivity(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,
SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup) {
// ...
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask, allowPendingRemoteAnimationRegistryLookup);
// ...
return getExternalResult(mLastStartActivityResult);
}
// 2
private int startActivity(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,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
// ...
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity);
}
// 3
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
// ...
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
// ...
return result;
}
// 4
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
// ...
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack,mStartActivity,
mOptions);
// ...
return START_SUCCESS;
}
可以看到經(jīng)過一系列調(diào)用(省略了大量代碼)最終走到了mSupervisor.resumeFocusedStackTopActivityLocked()
方法胡岔,mSupervisor的類型是ActivityStackSupervisor,我們接著來看ActivityStackSupervisor的resumeFocusedStackTopActivityLocked()
方法:
ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
// ...
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
// ...
}
方法內(nèi)部調(diào)用了targetStack.resumeTopActivityUncheckedLocked()
方法枷餐,targetStack的類型是ActivityStack靶瘸,我們來看它的resumeTopActivityUncheckedLocked()
方法:
ActivityStack的resumeTopActivityUncheckedLocked方法
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
// ...
result = resumeTopActivityInnerLocked(prev, options);
// ...
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// ...
mStackSupervisor.startSpecificActivityLocked(next, true, false);
// ...
return true;
}
最后又回到了ActivityStackSupervisor的startSpecificActivityLocked()
方法。
ActivityStackSupervisor的startSpecificActivityLocked方法
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// 獲取應(yīng)用進程
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
getLaunchTimeTracker().setLaunchTime(r);
if (app != null && app.thread != null) {
// 進程已創(chuàng)建
try {
// ...
// 核心代碼
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.
}
// 進程不存在則創(chuàng)建應(yīng)用進程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
方法內(nèi)部首先判斷了應(yīng)用程序進程是否存在毛肋,如果進程已創(chuàng)建就調(diào)用realStartActivityLocked()
方法怨咪,否則執(zhí)行mService.startProcessLocked()
方法常見應(yīng)用進程,mService就是ActivityManagerService對象润匙。本文只討論Activity的啟動流程诗眨,因此默認進程已創(chuàng)建,關(guān)于進程未創(chuàng)建的情況孕讳,對應(yīng)于點擊應(yīng)用圖標啟動App的過程匠楚,之后我會再利用一篇筆記進行分析。接下來我們來看一下realStartActivityLocked()
方法:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
// ...
// 創(chuàng)建Activity啟動事務(wù)
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// 執(zhí)行事務(wù)
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
// ...
}
mService.getLifecycleManager()
方法獲取到的是一個ClientLifecycleManager對象厂财,用來管理Activity的生命周期芋簿,可以看到realStartActivityLocked()
方法內(nèi)創(chuàng)建了一個ClientTransaction,表示Activity的啟動事務(wù)璃饱,最后調(diào)用ClientLifecycleManager的scheduleTransaction()
方法執(zhí)行該事務(wù)与斤。接下來我們來看ClientLifecycleManager的scheduleTransaction()
方法:
ClientLifecycleManager的scheduleTransaction方法
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
接著調(diào)用了ClientTransaction的schedule()
方法:
ClientTransaction的schedule方法
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
mClient的類型是IApplicationThread,最開始也提到過帜平,ApplicationThread實現(xiàn)了IApplicationThread接口幽告,再回過頭看上面的逐級調(diào)用,不難發(fā)現(xiàn)這里的mClient就是最開始傳入的ApplicationThread對象裆甩,因此我們直接來看ApplicationThread的scheduleTransaction()
方法:
ApplicationThread的scheduleTransaction方法
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
這里又調(diào)用了ActivityThread的scheduleTransaction()
方法冗锁,ActivityThread中沒有定義這個方法,它定義在ActivityThread的父類ClientTransactionHandler中嗤栓。
ClientTransactionHandler的scheduleTransaction方法
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
方法內(nèi)部調(diào)用了sendMessage()
方法冻河,該方法是一個抽象方法箍邮,它的實現(xiàn)在ActivityThread中。
ActivityThread的sendMessage方法
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1) {
sendMessage(what, obj, arg1, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2) {
sendMessage(what, obj, arg1, arg2, false);
}
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);
}
mH的類型是H叨叙,是ActivityThread內(nèi)部定義的一個Handler類锭弊,sendMessage()
方法所做的就是創(chuàng)建并向Handler發(fā)送一個消息,這個消息的what值為EXECUTE_TRANSACTION擂错。值得一提的是味滞,在Android 9.0以下版本中,H中定義了LAUNCH_ACTIVITY钮呀、PAUSE_ACTIVITY剑鞍、RESUME_ACTIVITY這些生命周期相關(guān)的消息,而在Android 9.0中已經(jīng)去掉了這些消息爽醋,取而代之的就是EXECUTE_TRANSACTION這個消息蚁署。下面我們就來看H的handleMessage()
方法,找到對EXECUTE_TRANSACTION這個消息的處理蚂四。
public void handleMessage(Message msg) {
// ...
switch (msg.what) {
// ...
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
// 核心代碼
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
// ...
}
// ...
}
這里的核心代碼是mTransactionExecutor.execute(transaction)
光戈,mTransactionExecutor的類型是TransactionExecutor,我們來看TransactionExecutor的execute()
方法:
TransactionExecutor的execute方法
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
public void executeCallbacks(ClientTransaction transaction) {
// 這里的callbacks是上面調(diào)用ActivityStackSupervisor中realStartActivityLocked方法時賦值的
// ClientTransactionItem的實際類型為LaunchActivityItem
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
// ...
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
final int postExecutionState = item.getPostExecutionState();
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());
// ...
// 核心代碼
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
// ...
}
}
execute()
方法中調(diào)用了兩個方法:executeCallbacks(transaction)
和executeLifecycleState(transaction)
遂赠。我們先不去管executeLifecycleState()
方法久妆,直接來看executeCallbacks()
方法,方法內(nèi)部首先獲取了ClientTransaction中的callbacks解愤,這里的callbacks是上面調(diào)用ActivityStackSupervisor中realStartActivityLocked()
方法時賦值的镇饺,類型為LaunchActivityItem,之后會調(diào)用LaunchActivityItem的execute()
方法送讲。
LaunchActivityItem的execute方法
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
// ...
// 核心代碼
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
// ...
}
方法內(nèi)部調(diào)用了ClientTransactionHandler的handleLaunchActivity()
方法奸笤,前面也提到過ActivityThread繼承自ClientTransactionHandler,因次這里實際上調(diào)用的是ActivityThread的handleLaunchActivity()
方法哼鬓,終于回到了我們熟悉的類中监右。
ActivityThread的handleLaunchActivity方法
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
// ...
// 核心代碼
final Activity a = performLaunchActivity(r, customIntent);
// ...
return a;
}
handleLaunchActivity()
方法中又調(diào)用了performLaunchActivity()
方法:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// ...
java.lang.ClassLoader cl = appContext.getClassLoader();
// 1.創(chuàng)建Activity對象
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
// ...
// 2.創(chuàng)建Application對象,如果已經(jīng)創(chuàng)建則不會重復(fù)創(chuàng)建
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
// ...
if (activity != null) {
// ...
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
// 3.創(chuàng)建PhoneWindow
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);
// ...
// 4.調(diào)用onCreate()方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
// ...
r.activity = activity;
}
// ...
return activity;
}
performLaunchActivity()
方法內(nèi)部主要做了一下幾件事:
- 調(diào)用Instrumentation的
newActivity
方法創(chuàng)建Activity對象
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
String pkg = intent != null && intent.getComponent() != null
? intent.getComponent().getPackageName() : null;
return getFactory(pkg).instantiateActivity(cl, className, intent);
}
// AppComponentFactory的instantiateActivity方法
public Activity instantiateActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance();
}
可以看出Instrumentation的newActivity
方法內(nèi)部就是通過類加載器來創(chuàng)建Activity對象异希。
- 調(diào)用
r.packageInfo.makeApplication()
方法創(chuàng)建Application對象
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
// 判斷Application對象是否已創(chuàng)建健盒,如果已創(chuàng)建就直接返回
if (mApplication != null) {
return mApplication;
}
// ...
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 核心代碼
// 通過類加載器創(chuàng)建Application對象
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
mActivityThread.mAllApplications.add(app);
mApplication = app;
// ...
return app;
}
這里的r.packageInfo類型為LoadedApk。makeApplication()
方法內(nèi)部首先判斷了Application對象是否已創(chuàng)建称簿,保證了只有一個Application對象扣癣。Application對象是通過調(diào)用Instrumentation的newApplication()
方法來創(chuàng)建的,方法內(nèi)部同樣使用了類加載器憨降,這里就不展示了父虑。
- 調(diào)用Activity的
attach()
方法
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback) {
// ...
// 創(chuàng)建PhoneWindow
mWindow = new PhoneWindow(this, window, activityConfigCallback);
// ...
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
// ...
}
attach()
方法主要做了兩件事:創(chuàng)建Window對象,類型為PhotoWindow授药;為Window對象關(guān)聯(lián)WindowManager士嚎,這屬于View繪制的研究范疇呜魄,本文中就不具體研究了。
- 調(diào)用Instrumentation的
callActivityOnCreate()
方法
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
方法內(nèi)部調(diào)用了Activity的performCreate()
方法莱衩。
Activity的performCreate方法
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
// ...
// 調(diào)用Activity的onCreate()方法
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
// ...
}
方法內(nèi)部調(diào)用了我們最熟悉的Activity生命周期onCreate()
方法爵嗅,到這里Activity的啟動流程基本上就分析得差不多了。不過你可能還會有個疑惑笨蚁,onCreate()
之后的onStart()
和onResume()
是在哪里調(diào)用的呢睹晒,我在這里也是繞了好久,我看到網(wǎng)上的一些源碼分析中有一些是在performLaunchActivity()
方法最后調(diào)用了Activity的performStart()
方法括细,進而回調(diào)了onStart()
方法册招,可能是由于版本不同,我這里并沒有調(diào)用該方法勒极。還記得上面的分析中在TransactionExecutor的execute()
方法中調(diào)用的executeLifecycleState()
嗎,是時候來看一下這個方法了虑鼎。
TransactionExecutor的executeLifecycleState方法
private void executeLifecycleState(ClientTransaction transaction) {
// lifecycleItem的類型為ResumeActivityItem
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
// ...
// Cycle to the state right before the final requested state.
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
這里transaction.getLifecycleStateRequest()
獲取到的ActivityLifecycleItem同樣是在之前調(diào)用ActivityStackSupervisor中的realStartActivityLocked()
方法時賦值的辱匿,類型為ResumeActivityItem,之后調(diào)用了cycleToPath()
方法炫彩。
private void cycleToPath(ActivityClientRecord r, int finish,
boolean excludeLastState) {
final int start = r.getLifecycleState();
log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
performLifecycleSequence(r, path);
}
cycleToPath()
方法內(nèi)部會調(diào)用TransactionExecutorHelper的getLifecyclePath()
方法匾七,該方法的作用是根據(jù)傳入的起始生命周期狀態(tài)和最終生命周期狀態(tài)生成一個數(shù)組,比如當前生命周期狀態(tài)為為ON_CREATE江兢,而finish狀態(tài)為lifecycleItem.getTargetState()
昨忆,也就是ResumeActivityItem.getTargetState()
即ON_RESUME,中間間隔了一個生命周期狀態(tài)ON_START杉允,因此這里生成的數(shù)組包含一個元素ON_START邑贴。Activity生命周期對應(yīng)的狀態(tài)值如下:
public static final int ON_CREATE = 1;
public static final int ON_START = 2;
public static final int ON_RESUME = 3;
public static final int ON_PAUSE = 4;
public static final int ON_STOP = 5;
public static final int ON_DESTROY = 6;
public static final int ON_RESTART = 7;
接下來會調(diào)用performLifecycleSequence()
方法:
private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
log("Transitioning to state: " + state);
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r.token, false /* show */,
0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
可以看出這里會根據(jù)上一步生成的數(shù)組依次執(zhí)行相應(yīng)的生命周期相關(guān)方法,由于這里的數(shù)組只包含一個元素ON_START叔磷,因此會執(zhí)行mTransactionHandler.handleStartActivity()
方法拢驾,之后的步驟就和onCreate()
的執(zhí)行過程很相似了,即調(diào)用ActivityThread的handleStartActivity()
方法改基,方法內(nèi)部調(diào)用Activity的performStart()
方法繁疤,繼而回調(diào)生命周期onStart()
方法,這里就不具體展示源碼分析了秕狰。
接下來我們回到executeLifecycleState()
方法中稠腊,在執(zhí)行cycleToPath()
方法后調(diào)用了lifecycleItem.execute()
方法,由于這里的lifecycleItem是ResumeActivityItem鸣哀,因此我們來看ResumeActivityItem的execute()
方法:
ResumeActivityItem的execute方法
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
// 核心代碼
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
可以看到和此前的兩個生命周期方法調(diào)用類似架忌,同樣是先調(diào)用了ActivityThread的handleResumeActivity()
方法,之后調(diào)用performResumeActivity()
诺舔,最后會調(diào)用onResume()
生命周期方法鳖昌。
上述的流程只是我的簡單分析备畦,實際過程肯定要更復(fù)雜,個人水平比較有限许昨,因此只能這樣簡單地分析一下(PS:加斷點調(diào)試把我搞得有點蒙懂盐,實際執(zhí)行的流程其實并不是像我分析得這樣,有的方法會執(zhí)行多次)糕档,不正確的地方歡迎指出莉恼。
到這里整個Activity的啟動流程就分析得差不多了,實際的流程要比分析的復(fù)雜得多速那,也會涉及到很多其他的知識點俐银,包括View的繪制和進程的創(chuàng)建等等,由于水平有限很多地方只能淺嘗輒止端仰,太過深入源碼容易迷失方向捶惜。上一張流程圖總結(jié)一下吧:
從分析和圖中我們也能發(fā)現(xiàn)在Activity的啟動流程中有幾個類起到了至關(guān)重要的作用:
- Instrumentation
最開始調(diào)用AMS方法,最后創(chuàng)建Activity和Application對象都是通過它來實現(xiàn)的荔烧。
- ActivityManagerService
Android中的核心服務(wù)吱七,應(yīng)用進程通過Binder機制可以調(diào)用系統(tǒng)服務(wù)。
- ActivityThread
應(yīng)用程序的入口鹤竭,Activity各個生命周期的調(diào)用都是通過ActivityThread內(nèi)部的Handler接收和處理消息來實現(xiàn)的踊餐。
上面的流程圖我已經(jīng)上傳到了github,如果不清晰的話可以查看原圖
總結(jié)
本文是針對Android 9.0(API Level 28)的源碼進行分析的臀稚,與其他版本會有一些不同吝岭,但是大體流程不會差太多,主要差別就是在調(diào)用realStartActivityLocked()
方法之后Handler的消息處理吧寺,有興趣的話可以自行查看源碼窜管。由于個人水平不足,很多地方可能分析得不準確撮执,也不夠全面微峰,希望大佬們可以指出。
最后總結(jié)一下我的一些心得抒钱,對于目前的我來說分析源碼實在是一件枯燥痛苦的事蜓肆,需要了解的知識點有很多,文章前前后后寫了很久谋币,中間中斷了好多次仗扬,也借鑒了很多大佬的成果,終于算是寫完了蕾额。但是拋開過程中的痛苦早芭,當真正把一個流程理順之后還是會覺得心情舒暢,雖然文章中的一些分析可能一段時間后還是會遺忘诅蝶,但是我收獲更多的是源碼閱讀和分析能力的提高退个,而且自己真正從頭分析了一遍之后再復(fù)習(xí)起來就會容易的多募壕。希望今后能夠更多地閱讀一些系統(tǒng)或者優(yōu)秀第三方庫的源碼,不斷提高自己语盈。
參考資料
死磕Android_App 啟動過程(含 Activity 啟動過程)
Android9.0 Activity啟動流程分析(三)
《Android開發(fā)藝術(shù)探索》