一、寫在前面
在開始之前,你需要知道下面幾點(diǎn):
- 有一份編譯好的 Android 源碼,現(xiàn)在的 AS 基本能滿足,動手跟著步驟走,理解更深刻
- 對 Binder 機(jī)制有一定的了解
- 本文基于 API 26,用什么版本的源碼并不重要,大體的流程并無本質(zhì)上的區(qū)別
- 從用戶手指觸摸點(diǎn)擊桌面圖標(biāo)到 Activity 啟動
關(guān)鍵類簡介
- ActivityManagerService:AMS 是 Android 中最核心的服務(wù)之一,主要負(fù)責(zé)系統(tǒng)中四大組件的啟動、切換、調(diào)度及應(yīng)用進(jìn)程的管理和調(diào)度等工作,其職責(zé)與操作系統(tǒng)中的進(jìn)程管理和調(diào)度模塊相類似,它本身也是一個(gè) Binder 的實(shí)現(xiàn)類,應(yīng)用進(jìn)程能通過 Binder 機(jī)制調(diào)用系統(tǒng)服務(wù)。
- ActivityThread:應(yīng)用的入口類,系統(tǒng)通過調(diào)用main函數(shù),開啟消息循環(huán)隊(duì)列。ActivityThread 所在線程被稱為應(yīng)用的主線程(UI 線程)。
- Instrumentation:工具類,它用來監(jiān)控應(yīng)用程序和系統(tǒng)的交互,包裝了 ActivityManagerService 的調(diào)用,一些插件化方案就是通過 hook 該類實(shí)現(xiàn)的。
- ActivityStarter:Activity 啟動的工具類,處理啟動 Activity 的各種 flag 。
- ActivityStackSupervisor:管理所有應(yīng)用的 Activity 的棧,其中 mFocusedStack 就是當(dāng)前應(yīng)用的 Activity 棧。
應(yīng)用進(jìn)程介紹
- 在大多數(shù)情況下,每個(gè) Android 應(yīng)用都在各自的 Linux 進(jìn)程中運(yùn)行。當(dāng)需要運(yùn)行應(yīng)用的一些代碼時(shí),系統(tǒng)會為應(yīng)用創(chuàng)建此進(jìn)程,并使其保持運(yùn)行,直到不再需要它且系統(tǒng)需要回收其內(nèi)存以供其他應(yīng)用使用。
- 應(yīng)用進(jìn)程的生命周期并不由應(yīng)用本身直接控制,而是由系統(tǒng)綜合多種因素來確定的,比如系統(tǒng)所知道的正在運(yùn)行的應(yīng)用部分、這些內(nèi)容對用戶的重要程度,以及系統(tǒng)中可用的總內(nèi)存量。這是 Android 非常獨(dú)特的一個(gè)基本功能。
- 當(dāng)應(yīng)用組件啟動且該應(yīng)用未運(yùn)行任何其他組件時(shí),Android 系統(tǒng)會使用單個(gè)執(zhí)行線程為應(yīng)用啟動新的 Linux 進(jìn)程。默認(rèn)情況下,同一應(yīng)用的所有組件會在相同的進(jìn)程和線程(稱為“主”線程)中運(yùn)行。如果某個(gè)應(yīng)用組件啟動且該應(yīng)用已存在進(jìn)程(因?yàn)榇嬖谠搼?yīng)用的其他組件),則該組件會在此進(jìn)程內(nèi)啟動并使用相同的執(zhí)行線程。但是,您可以安排應(yīng)用中的其他組件在單獨(dú)的進(jìn)程中運(yùn)行,并為任何進(jìn)程創(chuàng)建額外的線程。
- 每個(gè)應(yīng)用進(jìn)程都相當(dāng)于一個(gè) Sandbox 沙箱,Android 通過對每一個(gè)應(yīng)用分配一個(gè) UID,注意這里的 UID 不同于 Linux 系統(tǒng)的 User ID,可以將每個(gè)應(yīng)用理解為一個(gè) User ,只能對其目錄下的內(nèi)容具有訪問和讀寫權(quán)限。
- Android 利用遠(yuǎn)程過程調(diào)用 (RPC) 提供了一種進(jìn)程間通信 (IPC) 機(jī)制,在此機(jī)制中,系統(tǒng)會(在其他進(jìn)程中)遠(yuǎn)程執(zhí)行由 Activity 或其他應(yīng)用組件調(diào)用的方法,并將所有結(jié)果返回給調(diào)用方。因此,您需將方法調(diào)用及其數(shù)據(jù)分解至操作系統(tǒng)可識別的程度,并將其從本地進(jìn)程和地址空間傳輸至遠(yuǎn)程進(jìn)程和地址空間,然后在遠(yuǎn)程進(jìn)程中重新組裝并執(zhí)行該調(diào)用。然后,返回值將沿相反方向傳輸回來。Android 提供執(zhí)行這些 IPC 事務(wù)所需的全部代碼,因此您只需集中精力定義和實(shí)現(xiàn) RPC 編程接口。
下面這張圖可以補(bǔ)充理解一下進(jìn)程的概念:
二、流程分析
先來一張流程簡圖:
下面是流程詳細(xì)圖,帶你看完整個(gè)啟動流程及其所涉及到的類:
下面補(bǔ)充一張 Gityuan 大神的系統(tǒng)啟動架構(gòu)圖幫助理解,其實(shí)只要看看這張圖的上半部分就足夠了:
三、概述
簡單地講,從 用戶手指觸摸點(diǎn)擊桌面圖標(biāo)到 Activity啟動 可以用下面 4 步概括:
- 當(dāng)點(diǎn)擊桌面 App 的時(shí)候,發(fā)起進(jìn)程就是 Launcher 所在的進(jìn)程,啟動遠(yuǎn)程進(jìn)程,利用 Binder 發(fā)送消息給 system_server 進(jìn)程;
- 在 system_server 中,啟動進(jìn)程的操作會先調(diào)用
ActivityManagerService#startProcessLocked()
方法,該方法內(nèi)部調(diào)用Process.start(android.app.ActivityThread)
;而后通過 socket 通信告知 Zygote 進(jìn)程 fork 子進(jìn)程,即 app 進(jìn)程。進(jìn)程創(chuàng)建后將 ActivityThread 加載進(jìn)去,執(zhí)行ActivityThread#main()
方法;
- 在 app 進(jìn)程中,
main()
方法會實(shí)例化 ActivityThread,同時(shí)創(chuàng)建 ApplicationThread,Looper,Handler 對象,調(diào)用ActivityThread#attach(false)
方法進(jìn)行 Binder 通信,方法里面調(diào)用ActivityManagerService#attachApplication(mAppThread)
方法,將 thread 信息告知 ActivityManagerService , 接著 Looper 啟動循環(huán);
- 回到 system_server 中,
ActivityManagerService#attachApplication(mAppThread)
方法內(nèi)部調(diào)用了thread#bindApplication()
和mStackSupervisor#attachApplicationLocked()
我們依次講解這兩個(gè)方法;
4.1thread#bindApplication()
方法調(diào)用了ActivityThread#sendMessage(H.BIND_APPLICATION, data)
方法,最終走到了ActivityThread#handleBindApplication()
,進(jìn)而創(chuàng)建 Application 對象,然后調(diào)用Application#attach(context)
來綁定 Context ,創(chuàng)建完 Application 對象后便是調(diào)用mInstrumentation#callApplicationOnCreate()
執(zhí)行Application#onCreate()
生命周期;
4.2mStackSupervisor#attachApplicationLocked()
方法中調(diào)用app#thread#scheduleLaunchActivity()
即ActivityThread#ApplicationThread#scheduleLaunchActivity()
方法,進(jìn)而通過ActivityThread#sendMessage(H.LAUNCH_ACTIVITY, r)
方法,最終走到了ActivityThread#handleLaunchActivity()
,進(jìn)而創(chuàng)建 Activity 對象,然后調(diào)用activity.attach()
方法,再調(diào)用mInstrumentation#callActivityOnCreate()
執(zhí)行Activity#onCreate()
生命周期;
四、源碼調(diào)用探究
對應(yīng)本文第一張流程圖的每一個(gè)步驟,下面逐步來看看源碼是怎么調(diào)用的:
STEP 1
用戶點(diǎn)擊 app 圖標(biāo);
STEP 2
Launcher 捕獲點(diǎn)擊事件,調(diào)用 Activity#startActivity()
;
STEP 3
Activity#startActivity()
調(diào)用 Instrumentation;
Activity.java
@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,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
···
} else {
···
}
}
STEP 4
Instrumentation 通過 Binder 通信發(fā)送消息給 system_server 進(jìn)程,具體 調(diào)用 ActivityManager#getService()#startActivity()
,ActivityManager#getService()
的具體實(shí)現(xiàn)是 ActivityManagerService ;
Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
···
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;
}
ActivityManager.java
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;
}
};
STEP 5
ActivityManagerService 調(diào)用 ActivityStarter;
ActivityManagerService.java
@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) {
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,
"startActivityAsUser");
}
STEP 6
ActivityStarter 調(diào)用 ActivityStackSupervisor;
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 globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask, String reason) {
···
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, reason);
···
}
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, String reason) {
···
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
container, inTask);
···
return mLastStartActivityResult;
}
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,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask) {
···
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
options, inTask, outActivity);
}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
···
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
} finally {
···
}
···
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
···
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
···
} else {
···
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
···
}
···
}
STEP 7
ActivityStackSupervisor 調(diào)用 ActivityStack;
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
···
return false;
}
STEP 8
ActivityStack 回調(diào)到 ActivityStackSupervisor ;
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
···
try {
···
result = resumeTopActivityInnerLocked(prev, options);
} finally {
···
}
···
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
···
if (next.app != null && next.app.thread != null) {
···
} else {
···
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
···
}
STEP 9
ActivityStackSupervisor 回調(diào)到 ActivityManagerService,這里會判斷要啟動 App 的進(jìn)程是否存在,存在則通知進(jìn)程啟動 Activity,否則就先將進(jìn)程創(chuàng)建出來;
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
···
if (app != null && app.thread != null) {
try {
···
// 如果進(jìn)程已存在,則通知進(jìn)程啟動組件
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
···
}
}
// 否則先將進(jìn)程創(chuàng)建出來
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
STEP 10
接著我們來看看進(jìn)程尚未創(chuàng)建的情況,我們看到這里最終調(diào)用的是 Process#start()
來啟動進(jìn)程;
ActivityManagerService.java
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
···
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
···
}
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
···
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
ProcessStartResult startResult;
if (hostingType.equals("webview_service")) {
···
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
}
···
}
STEP 11
ActivityManagerService 通過 socket 通信告知 Zygote 進(jìn)程 fork 子進(jìn)程,即 app 進(jìn)程;
STEP 12
進(jìn)程創(chuàng)建后將 ActivityThread 加載進(jìn)去,執(zhí)行 ActivityThread#main()
方法,實(shí)例化 ActivityThread,同時(shí)創(chuàng)建 ApplicationThread,Looper,Hander 對象,調(diào)用 ActivityThread#attach(false) 方法進(jìn)行 Binder 通信, 接著 Looper 啟動循環(huán);
ActivityThread.java
public static void main(String[] args) {
···
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
···
Looper.loop();
···
}
private void attach(boolean system) {
···
if (!system) {
···
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
···
} else {
···
}
···
}
回到 system_server 中,ActivityManagerService#attachApplication(mAppThread)
方法內(nèi)部調(diào)用了 thread#bindApplication()
和 mStackSupervisor#attachApplicationLocked()
這兩個(gè)方法。
STEP 13
其中,thread#bindApplication()
方法調(diào)用了 ActivityThread#sendMessage(H.BIND_APPLICATION, data)
方法,最終走到了 ActivityThread#handleBindApplication()
,進(jìn)而創(chuàng)建 Application 對象,然后調(diào)用 Application#attach(context)
來綁定 Context ,創(chuàng)建完 Application 對象后便是調(diào)用 mInstrumentation#callApplicationOnCreate()
執(zhí)行 Application#onCreate()
生命周期;
ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
···
attachApplicationLocked(thread, callingPid);
···
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
···
try {
···
if (app.instr != null) {
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
}
···
} catch (Exception e) {
···
}
···
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
···
}
}
···
}
ActivityThread#ApplicationThread.java
public final void bindApplication(String processName, ApplicationInfo appInfo,
···
sendMessage(H.BIND_APPLICATION, data);
}
ActivityThread.java
private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
···
mH.sendMessage(msg);
}
我們來看看這個(gè) mH 的 handleMessage()
方法;
ActivityThread#H.java
public void handleMessage(Message msg) {
···
switch (msg.what) {
···
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
···
}
···
}
創(chuàng)建 mInstrumentation 對象,調(diào)用 data#info#makeApplication 來創(chuàng)建 Application 對象;
ActivityThread.java
private void handleBindApplication(AppBindData data) {
···
try {
// 創(chuàng)建 Application 實(shí)例
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
···
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
···
}
} finally {
···
}
···
}
LoadedApk.java
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
···
Application app = null;
···
try {
···
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
···
} catch (Exception e) {
···
}
···
if (instrumentation != null) {
try {
//執(zhí)行 Application#onCreate() 生命周期
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
···
}
}
···
return app;
}
STEP 14
mStackSupervisor#attachApplicationLocked()
方法中調(diào)用 app#thread#scheduleLaunchActivity()
即 ActivityThread#ApplicationThread#scheduleLaunchActivity()
方法,進(jìn)而通過 ActivityThread#sendMessage(H.LAUNCH_ACTIVITY, r)
方法,最終走到了 ActivityThread#handleLaunchActivity()
,進(jìn)而創(chuàng)建 Activity 對象,然后調(diào)用 activity.attach()
方法,再調(diào)用 mInstrumentation#callActivityOnCreate()
執(zhí)行 Activity#onCreate()
生命周期;
ActivityStackSupervisor.java
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
···
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
···
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
···
}
}
}
}
}
···
}
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,
// 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);
···
} catch (RemoteException e) {
···
}
···
}
ActivityThread#ApplicationThread.java
@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);
}
ActivityThread.java
private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
···
mH.sendMessage(msg);
}
我們同樣來看看這個(gè) mH 的 handleMessage()
方法;
ActivityThread#H.java
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
···
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
···
} break;
···
}
···
}
ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
···
Activity a = performLaunchActivity(r, customIntent);
···
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
···
Activity activity = null;
try {
//創(chuàng)建 Activity 對象
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
···
} catch (Exception e) {
···
}
try {
···
if (activity != null) {
···
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);
···
//執(zhí)行 Activity#onCreate() 生命周期
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
···
}
···
} catch (SuperNotCalledException e) {
···
} catch (Exception e) {
···
}
到這里,整個(gè) app 啟動流程以及源碼調(diào)用皆已分析完畢。