本文是 Android 系統(tǒng)學(xué)習(xí)系列文章中的第一章節(jié)第二小節(jié)內(nèi)容,從源碼出發(fā)說(shuō)明了 Android 應(yīng)用進(jìn)程是如何啟動(dòng)的,經(jīng)過(guò)哪些進(jìn)程的通力合作,它們是如何是設(shè)計(jì)的。。對(duì)此系列感興趣的同學(xué),可以收藏這個(gè)鏈接 Android 系統(tǒng)學(xué)習(xí),也可以使用 RSS 進(jìn)行訂閱。
閱讀的收益
討論的內(nèi)容也就是一個(gè)應(yīng)用進(jìn)程是如何啟動(dòng)的,私以為這一部分的內(nèi)容頗為重要,即便不了解細(xì)節(jié),也要知道其中的大體步驟。特別是針對(duì)我們應(yīng)用開(kāi)發(fā)者而言,理應(yīng)了解我們的 App 是如何被啟動(dòng)的,App 中的組件是如何被系統(tǒng)服務(wù)調(diào)用和組織的。
講應(yīng)用進(jìn)程啟動(dòng)的文章不是很多,也都沒(méi)有說(shuō)到點(diǎn)上,大抵都是對(duì)源碼的堆疊,沒(méi)有個(gè)人的理解在里面。如果非要看調(diào)用棧的話,在合適的地方掛上斷點(diǎn),或者通過(guò)輸出異常棧的方式都可以看到,如下圖所示。老羅的文章 Android應(yīng)用程序啟動(dòng)過(guò)程源代碼分析 事無(wú)巨細(xì),但感覺(jué)還是沒(méi)有說(shuō)到點(diǎn)子上,因而這篇文章只做到拋磚引玉的作用,希望有更好的文章出現(xiàn)。細(xì)節(jié)是復(fù)雜的,原理是簡(jiǎn)單的,這里盡可能地從原理角度出發(fā)進(jìn)行說(shuō)明,加深大家的理解。
對(duì)這篇文章閱讀后,你能了解從用戶點(diǎn)擊 Launcher 上的 App 圖標(biāo),到顯示出 App 界面時(shí)主要發(fā)生的事情,而通過(guò)對(duì)這個(gè)一過(guò)程的了解,將知曉以下知識(shí)點(diǎn)。
- Android Process 的創(chuàng)建過(guò)程,以及 Activity Manager Service 是如何參與這個(gè)步驟,以及在其中扮演的角色?
- Android 中所謂的主線程是怎么回事?主線程是誰(shuí)?又如何被創(chuàng)建的。
- Android 系統(tǒng)是如何節(jié)省進(jìn)程創(chuàng)建開(kāi)銷(xiāo)的?
應(yīng)用進(jìn)程簡(jiǎn)介
在 Android 中每一個(gè)應(yīng)用程序都被設(shè)計(jì)為單獨(dú)的進(jìn)程,應(yīng)用程序也可以根據(jù)自己的需要去決定是否需要啟用多個(gè)進(jìn)程,不過(guò)總而言之都與其他應(yīng)用程序和系統(tǒng)服務(wù)是相互獨(dú)立的。從解耦和系統(tǒng)穩(wěn)定性的角度上看都應(yīng)該運(yùn)行在不同的進(jìn)程上,畢竟不能因?yàn)閼?yīng)用程序的崩潰就影響到其他應(yīng)用進(jìn)程或者系統(tǒng)服務(wù)進(jìn)程。
應(yīng)用進(jìn)程不同于其他 Android 系統(tǒng)中的守護(hù)進(jìn)程,當(dāng)內(nèi)存不夠的時(shí)候,某些應(yīng)用進(jìn)程可能會(huì)被系統(tǒng)回收掉,因而應(yīng)用進(jìn)程也是有其生命周期的,更多信息參考 Android Developer 官網(wǎng)對(duì)于 Process 的教程 。Android 應(yīng)用組件不一定要運(yùn)行在單獨(dú)的進(jìn)程上,也可以運(yùn)行在多個(gè)進(jìn)程上,通過(guò)對(duì) Android 組件指定運(yùn)行的進(jìn)程 android:process,即可讓其運(yùn)行在其他線程上。
每個(gè)應(yīng)用進(jìn)程都相當(dāng)于一個(gè) Sandbox 沙箱,Android 通過(guò)對(duì)每一個(gè)應(yīng)用分配一個(gè) UID,注意這里的 UID 不同于 Linux 系統(tǒng)的 User ID,可以將每個(gè)應(yīng)用理解為一個(gè) User
,只能對(duì)其目錄下的內(nèi)容具有訪問(wèn)和讀寫(xiě)權(quán)限,這樣就從根源上保護(hù)了其他應(yīng)用程序,下圖說(shuō)明了其隔離效果。

Zygote 進(jìn)程
Zygote 的中文意思是受精卵,從這個(gè)意思里也可以看出 Zygote 進(jìn)程是用來(lái)分裂復(fù)制(fork)的,實(shí)際上所有的 App 進(jìn)程都是通過(guò)對(duì) Zygote 進(jìn)程的 Fork 得來(lái)的。當(dāng) app_process 啟動(dòng) Zygote 時(shí),Zygote 會(huì)在其啟動(dòng)后,預(yù)加載必要的 Java Classes(相關(guān)列表查看 預(yù)加載文件) 和 Resources,并啟動(dòng) System Server ,并打開(kāi) /dev/socket/zygote socket 去監(jiān)聽(tīng)啟動(dòng)應(yīng)用程序的請(qǐng)求,日后。在下面的代碼中,顯示了 Zygote 進(jìn)程如何啟動(dòng),和加載 System Server 的。

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
public static void main(String argv[]) {
// ...
registerZygoteSocket(socketName); // 開(kāi)啟 Zygote socket.
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(); // 預(yù)加載資源
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
gcAndFinalize(); // 觸發(fā) GC
if (startSystemServer) { // 啟動(dòng) System Server.
startSystemServer(abiList, socketName);
}
// ...
}

那么為何要做這種設(shè)計(jì)呢?每個(gè)應(yīng)用程序的運(yùn)行,都需要依托于相應(yīng)的運(yùn)行環(huán)境,而這個(gè)就是 Davlik (ART) 虛擬機(jī),但每次啟動(dòng)的開(kāi)銷(xiāo)較大,而通過(guò)對(duì) Zygote 進(jìn)程的 Fork,能夠提升不小的效率。并且在這個(gè)工程中,采用了 Copy-on-Write 的方式,極大程度上地復(fù)用了 Zygote 上面的資源。更多信息也可以參考我這篇博文 詳解 Android 是如何啟動(dòng)的。
App 應(yīng)用進(jìn)程啟動(dòng)
接下來(lái)的內(nèi)容涉及到很多 Binder 通信相關(guān)的東西,因此在閱讀本文前,建議查閱下 Binder 相關(guān)的文章,這里有下列文章供查考。
- Android Binder 完全解析(一)概述
- Android Binder 完全解析(二)設(shè)計(jì)詳解
- Android Binder 完全解析(三)AIDL實(shí)現(xiàn)原理分析
ActivityManager 架構(gòu)
在我們編程過(guò)程中,涉及到許多 Activity 跳轉(zhuǎn)的事情,在 Launcher 中點(diǎn)擊 Icon 進(jìn)行跳轉(zhuǎn)也是同樣的道理,調(diào)用 context.startActivity(intent) 方法。Launcher 出于一個(gè)線程,而啟動(dòng)的 App 則運(yùn)行在另一個(gè)進(jìn)程中,在這其中勢(shì)必牽涉到跨進(jìn)程 (IPC) 調(diào)用,這樣復(fù)雜的過(guò)程顯然需要一種中介者,或者一個(gè)系統(tǒng)來(lái)進(jìn)行中轉(zhuǎn)和管理,而這個(gè)服務(wù)就是 ActivityManagerService。
ActivityManagerService 作為一個(gè)守護(hù)進(jìn)程運(yùn)行在 Android Framework 中,如果讓開(kāi)發(fā)者直接接觸這個(gè)類(lèi)的話,就需要開(kāi)發(fā)者自行處理 IPC 調(diào)用的問(wèn)題,且這有不利于 Android 系統(tǒng)進(jìn)行安全校驗(yàn)等工作。因而 Android 系統(tǒng)實(shí)現(xiàn)了 ActivityManager,通過(guò)這個(gè) ActivityManager 作為一個(gè)入口,變相地和 ActivityManagerService 打交道。這種模式在 Android 系統(tǒng)中極為常見(jiàn),類(lèi)似的還有 WifiManager, LocationManager,WindowsManager 等等。而這些 Manger 在背后調(diào)用的東西就是前面提及的 Binder 機(jī)制。下面以 ActivityManger 為例看看其背后的運(yùn)作方式。
Binder 體系架構(gòu)可以分為 Client 和 Server 兩端,為了更方便 Client 的調(diào)用,這次采用了 AIDL 的方式,具體參考鏈接 Android Binder 完全解析(三)AIDL實(shí)現(xiàn)原理分析 。這里再用類(lèi)比的方式來(lái)說(shuō)明,方便大家理解。歷史上有不少垂簾聽(tīng)政的故事,背后操作的人實(shí)際是通過(guò)控制傀儡來(lái)控制朝政,通過(guò)給傀儡皇帝傳遞命令,傀儡皇帝只是復(fù)述命令,起到傳遞的作用。更有甚者,不想去上朝的控權(quán)者,會(huì)通過(guò)手下的太監(jiān)或者婢女,轉(zhuǎn)述給傀儡皇上。這種模式被我們稱(chēng)為代理模式,ActivityManger 所使用的就是這種模式。
首先這里要針對(duì)要執(zhí)行的命令進(jìn)行抽象,這樣掌權(quán)者、太監(jiān)、皇上和朝政才能聽(tīng)懂。IActivityManager 就是對(duì)這個(gè)進(jìn)行的抽象,點(diǎn)擊查看 源碼,這幾種就包括常見(jiàn)的 startActivity, showWaitingForDebugger, finishActivity 等等。ActivityManagerProxy 就相當(dāng)于其他的太監(jiān)或者婢女,Proxy 不需要懂具體的業(yè)務(wù),只需要把指令傳遞過(guò)去就行。ActivityManagerService 就是具體的執(zhí)行者,就是大臣們。ActivityManger 則就是具體的業(yè)務(wù)邏輯的外觀類(lèi)(參加GOF的設(shè)計(jì)模式),也就是具體的掌權(quán)者們。它們的關(guān)系如下圖所示:

源碼分析從 Launcher 到 ActivityManager 啟動(dòng)步驟
接下來(lái)分析下,在源碼里是具體操作的,也驗(yàn)證我們前面的說(shuō)法。
(1) 點(diǎn)擊 Launcher 的圖標(biāo),會(huì)調(diào)用到 Activity 的 startActivity 方法。在繼續(xù)往下看過(guò)去,這個(gè)里面會(huì)調(diào)用到 startActivityForResult 方法,在 startActivityForResult 方法中,疏通同歸,最后會(huì)調(diào)用 mInstrumentation.execStartActivity 方法。
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
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);
} else {
// ### ...
}
}
(2) Instrumentation 執(zhí)行 execStartActivity 方法。參數(shù)里面中的 contextThread 和 token 對(duì)象都是 IBinder 類(lèi)型,而 Binder 可以在跨進(jìn)程調(diào)用中依舊充當(dāng) Token 的角色,在多進(jìn)程中由 Binder Driver 保證依然可以是唯一的。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
// monitor ...
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) {
}
return null;
}
(3) ActivityManagerNative.getDefault().startActivity。getDefault 中實(shí)際返回的就是 Proxy 對(duì)象,在實(shí)際中只起到代理的重要,并不進(jìn)行邏輯處理。
先看看 ActivityManagerNative.getDefault() 中的實(shí)現(xiàn)。
/**
* Retrieve the system's default/global activity manager.
*/
static public IActivityManager getDefault() {
return gDefault.get();
}
IActivityManager 根據(jù)前文的描述即是對(duì)于可操作接口的抽象,Singleton 則是對(duì)單例對(duì)象的封裝。也就是說(shuō) gDefault 返回了實(shí)現(xiàn) IActivityManager 的單例。
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;
}
};
/**
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*/
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);
}
在 asInterface 中返回了 ActivityManagerProxy, 這就是前文提及的 太監(jiān)和婢女 角色,我們?cè)倏纯?ActivityManagerProxy 內(nèi)部是如何工作的。
(4) ActivityManagerProxy 的實(shí)現(xiàn)。從源碼里面可以看出,ActivityManagerProxy 將遠(yuǎn)程 Binder 作為構(gòu)造函數(shù)的參數(shù),而在 startActivity 方法中,通過(guò)遠(yuǎn)程 Binder 對(duì)象的 transact 方法,將參數(shù)寫(xiě)入到 data 中,在遠(yuǎn)程執(zhí)行完畢后,結(jié)果寫(xiě)入到 reply 里。這里實(shí)實(shí)在在地起到了 Proxy 的作用,只負(fù)責(zé)數(shù)據(jù)的傳輸。重點(diǎn)在下面這行代碼:
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
class ActivityManagerProxy implements IActivityManager {
public ActivityManagerProxy(IBinder remote) {
mRemote = remote;
}
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
// other methods.
}
(5) ActivityManagerService 的調(diào)用。
在上部分提及的 ActivityManagerProxy 中在構(gòu)造函數(shù)里傳入的 mRemote 遠(yuǎn)程Binder 是什么了?答案就在前面提及的 gDefault 里面。
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;
}
};
IBinder b = ServiceManager.getService("activity");
上面這段代碼返回的即是 ActivityManagerService。所有的系統(tǒng)服務(wù)都是 IBinder 對(duì)象,即他們必須支持遠(yuǎn)程調(diào)用。而每個(gè)系統(tǒng)服務(wù)都會(huì)通過(guò)在 ServiceManager 注冊(cè)別名的方式,告知 ServiceManager 通過(guò)相應(yīng)的別名即可訪問(wèn)到我。而 activity 正是 ActivityManagerService 的別名。
從 ActivityManagerService 到 進(jìn)程啟動(dòng)
ActivityManagerService 在接受到相應(yīng)的 Intent 請(qǐng)求后(Activity、Broadcast、Service、ContentProvider),會(huì)查看是否需要進(jìn)行新建進(jìn)程的工作,這里以 Activity 為例,其他組件的步驟與此原理相同,就不再贅述。
(1) ActivityManagerService 在啟動(dòng) Activity 之前,首先通過(guò) resolveIntent 方法,來(lái)得到相應(yīng)的 ResolveInfo,其后通過(guò)調(diào)用 startActivityLocked 往下啟動(dòng) Activity。
try {
ResolveInfo rInfo =
AppGlobals.getPackageManager().resolveIntent(
intent, null,
PackageManager.MATCH_DEFAULT_ONLY
| ActivityManagerService.STOCK_PM_FLAGS, userId);
aInfo = rInfo != null ? rInfo.activityInfo : null;
aInfo = mService.getActivityInfoForUser(aInfo, userId);
} catch (RemoteException e) {
aInfo = null;
}
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, voiceInteractor, resultTo, resultWho,
requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options,
componentSpecified, null, container, inTask);
(2) startSpecificActivityLocked 方法,判斷是否需要新建進(jìn)程。從代碼中看出,這里對(duì) ProcessRecord 進(jìn)行了判斷,ProcessRecord 就是響應(yīng)的進(jìn)程記錄,如果存在相應(yīng)的進(jìn)程,就啟動(dòng)相應(yīng)的 Activity, 否則將創(chuàng)建進(jìn)程。mService.startProcessLocked 這個(gè)方法實(shí)現(xiàn)了開(kāi)啟進(jìn)程,下面再看看里面的實(shí)現(xiàn)。
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {
try {
// ignore some code...
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);
}
(3) startProcessLocked 在內(nèi)部調(diào)用了 Process.start 方法,并且指定了 android.app.ActivityThread 作為進(jìn)程的入口,進(jìn)程啟動(dòng)后,將調(diào)用 android.app.ActivityThread 的 main 方法。
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
// ...
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
// ...
}
(4) 在 Process.start 方法中,實(shí)際調(diào)用的是 startViaZygote 方法,在這個(gè)方法里通過(guò) openZygoteSocketIfNeeded 打開(kāi) Zygote 的 socket,并通過(guò) zygoteSendArgsAndGetResult 進(jìn)行交互。
根據(jù)前文提及的內(nèi)容,zygote 開(kāi)啟了一個(gè) socket 監(jiān)聽(tīng)功能,監(jiān)聽(tīng)需要?jiǎng)?chuàng)建 Process 的請(qǐng)求,因而在這里,我們?nèi)ゲ榭?Zygote 的代碼,看其是怎么監(jiān)聽(tīng)請(qǐng)求的。
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
(5) ZygoteInit.runSelectLoop 方法,從源碼的實(shí)現(xiàn)中可以看出,這里是不斷地取 Socket 建立的鏈接(ZygoteConnection),然后調(diào)用 ZygoteConnection 中的 runOnce 方法。
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
FileDescriptor[] fdArray = new FileDescriptor[4];
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
int loopCount = GC_LOOP_COUNT;
while (true) {
int index;
/*
* Call gc() before we block in select().
* It's work that has to be done anyway, and it's better
* to avoid making every child do it. It will also
* madvise() any free memory as a side-effect.
*
* Don't call it every time, because walking the entire
* heap is a lot of overhead to free a few hundred bytes.
*/
if (loopCount <= 0) {
gc();
loopCount = GC_LOOP_COUNT;
} else {
loopCount--;
}
try {
fdArray = fds.toArray(fdArray);
index = selectReadable(fdArray);
} catch (IOException ex) {
throw new RuntimeException("Error in select()", ex);
}
if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDescriptor());
} else {
boolean done;
done = peers.get(index).runOnce();
if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
}
(6) ZygoteConnection.runOnce 方法里,fork 了 Zygote 進(jìn)程,這就是 應(yīng)用進(jìn)程 了,并返回相應(yīng)的 process id,其具體實(shí)現(xiàn)是本地方法,這里就不再深究了。如果得到相應(yīng)的 Pid,接下來(lái)看看應(yīng)用進(jìn)程是如何初始化的。
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
try {
if (pid == 0) {
// in child
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
// should never get here, the child is expected to either
// throw ZygoteInit.MethodAndArgsCaller or exec().
return true;
} else {
// in parent...pid of < 0 means failure
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
(7) handleChildProc 方法,其中的重點(diǎn)就在 RuntimeInit.zygoteInit 方法 和 ZygoteInit.invokeStaticMain 方法。一個(gè)調(diào)用初始化了相應(yīng)的進(jìn)程,另一個(gè)在調(diào)用了進(jìn)程的 main 方法。
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
if (parsedArgs.runtimeInit) {
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
pipeFd, parsedArgs.remainingArgs);
} else {
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
try {
ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
} catch (RuntimeException ex) {
logAndPrintError(newStderr, "Error starting.", ex);
}
}
在 RuntimeInit.zygoteInit 方法里實(shí)現(xiàn)了相應(yīng)的 AndroidRuntime 初始化,并初始化 Binder Driver 相關(guān)的文件,同時(shí)設(shè)置了 UncaughtHandler(應(yīng)用程序崩潰)。在這個(gè)方法調(diào)用結(jié)束后,應(yīng)用進(jìn)程就具備與相應(yīng)系統(tǒng)服務(wù)進(jìn)行 IPC 通信的能力。
(8) ZygoteInit.invokeStaticMain 通過(guò)反射調(diào)用了 ZygoteInit.MethodAndArgsCaller,而這個(gè)就是相應(yīng)的 ActivityThread.java 中的 main 方法,其所運(yùn)行的進(jìn)程,就是大家耳熟能祥的主線程,也成為 UI 線程。
static void invokeStaticMain(ClassLoader loader,
String className, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl;
try {
cl = loader.loadClass(className);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
到此為止,整個(gè)應(yīng)用進(jìn)程啟動(dòng)完畢。
應(yīng)用進(jìn)程啟動(dòng)總結(jié)

Launcher 中的 Icon 點(diǎn)擊,broadcast 發(fā)送,啟動(dòng) Service 等組件見(jiàn)的跳轉(zhuǎn),都會(huì)通過(guò) AndroidManagerProxy 來(lái)進(jìn)行中轉(zhuǎn),而 AndroidManagerProxy 通過(guò)向 SystemServer 請(qǐng)求名為 Activity 的 ActivityManagerService 的 Binder 對(duì)象,這個(gè) Binder 對(duì)象可以粗略地看作是 ActivityManagerService 的句柄,從 Binder 對(duì)象可實(shí)際操作 ActivityManagerService。
ActivityManagerService 在實(shí)際啟動(dòng)相應(yīng)組件時(shí),會(huì)先判斷是否有相應(yīng)的 ProcessRecord,如果不存在,就需要新建進(jìn)程,這個(gè)進(jìn)程就是相應(yīng)的應(yīng)用進(jìn)程。ActivityManagerService 通過(guò) Socket 通信的方式和 Zygote 進(jìn)行協(xié)商,Zygote 在其監(jiān)聽(tīng)的 /dev/socket/zygote socket 中發(fā)現(xiàn)有需要?jiǎng)?chuàng)建進(jìn)程的請(qǐng)求后,會(huì) fork 自身,并返回相應(yīng)的 Process Id。這個(gè) Process 會(huì)進(jìn)行相應(yīng)的初始化,使得其具備與系統(tǒng)服務(wù)進(jìn)行 IPC 通信的能力,在此之后,調(diào)用 ActivityThread 中的 main 方法,開(kāi)啟 Looper,主線程啟動(dòng)。到此為止,整個(gè)應(yīng)用進(jìn)程啟動(dòng)完畢。
參考文獻(xiàn)
- Android應(yīng)用程序進(jìn)程啟動(dòng)過(guò)程的源代碼分析
- Android應(yīng)用程序線程消息循環(huán)模型分析
- startActivity流程分析(一)
- Android四大組件 Activity啟動(dòng)過(guò)程源碼分析
- Android Application Launch
文檔信息
- 版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名(創(chuàng)意共享3.0許可證)
- 發(fā)表日期: 2016年6月26日
- 社交媒體: weibo
- Feed訂閱:www.woaitqs.cc/feed.xml