Android 中所有應(yīng)用的進(jìn)程都是從 Zygote 分裂出來的,而進(jìn)程也是承載各種應(yīng)用埋合、服務(wù)的基礎(chǔ)备徐,所以啟動任何的服務(wù)和應(yīng)用的第一步就是創(chuàng)建一個進(jìn)程。
上一篇 介紹了 Zygote 啟動后開啟了一個 socket 等待處理客戶端的請求甚颂,本文就主要介紹 AMS 通過 socket 請求 Zygote 創(chuàng)建進(jìn)程的過程
1 AMS.startProcessLocked
當(dāng)啟動一個應(yīng)用時蜜猾,首先需要創(chuàng)建這個應(yīng)用對應(yīng)的進(jìn)程秀菱。具體是怎樣走到 AMS.startProcessLocked 這一步的,需要單獨(dú)一篇文章來介紹蹭睡,簡單的說衍菱,當(dāng)我們調(diào)用 startActivity 啟動一個應(yīng)用時,最終就會調(diào)用到AMS.startProcessLocked 這一步肩豁。注意脊串,AMS 是在 SystemServer 進(jìn)程中執(zhí)行,Android 系統(tǒng)啟動流程總結(jié) 第4節(jié)有介紹清钥,最終在 SystemServer 進(jìn)程中啟動了 AMS洪规。
startProcessLocked() 這個方法看起來很長,其實關(guān)鍵的就這一句
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);
Process.start
-> ZygoteProcess.start
-> ZygoteProcess.startViaZygote
-> ZygoteProcess.zygoteSendArgsAndGetResult(ZygoteState zygoteState, ArrayList<String> args)
(ZygotePorcess.ZygoteState 這個內(nèi)部類循捺,負(fù)責(zé)與 Zygote 建立 socket 連接)
經(jīng)過層層調(diào)用斩例,最終 zygoteSendArgsAndGetResult 就通過 ZygoteState 把一堆參數(shù)發(fā)給 Zygote,接下來就是看 Zygote 的處理
2. Zygote 處理請求
Zygote在啟動之后从橘,調(diào)用 ZygoteServer.runSelectLoop 進(jìn)入等待請求的死循環(huán)中:
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList); // 1. 阻塞在這一步念赶,直到收到連接請求
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done = peers.get(i).runOnce(this); // 2. 收到請求后再循環(huán)一次進(jìn)入該執(zhí)行分支
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
private ZygoteConnection acceptCommandPeer(String abiList) {
try {
return createNewConnection(mServerSocket.accept(), abiList);
} catch (IOException ex) {
throw new RuntimeException(
"IOException during accept()", ex);
}
}
protected ZygoteConnection createNewConnection(LocalSocket socket, String abiList)
throws IOException {
return new ZygoteConnection(socket, abiList);
}
mServerSocket 是一個 LocalServerSocket 對象,其 accept() 方法會一直租塞直到有收到連接請求恰力,之后創(chuàng)建一個 ZygoteConnection叉谜,然后再一輪 while 循環(huán)就進(jìn)入到注釋2處的執(zhí)行分支,調(diào)用 ZygoteConnection.runOnce 方法踩萎。
ZygoteConnection.runOnce()
ZygoteConnection 中保存了一個 socket 對象停局,從中讀取解析請求參數(shù)后,最終調(diào)用 Zygote.forkAndSpecialize 創(chuàng)建出了新的進(jìn)程香府,之后分兩路分別調(diào)用 handleChildProc() 和 handleParentProc() 處理子進(jìn)程和 Zygote 進(jìn)程董栽。
- handleChildProc() 中的邏輯和 Android 系統(tǒng)啟動流程總結(jié) 中第3節(jié)介紹 SystemServer 的啟動很像,也是進(jìn)入 RuntimeInit.zygoteInit()企孩,最終通過拋異常的方法調(diào)用對應(yīng) Java 類的 mian() 函數(shù)锭碳,如果是啟動應(yīng)用或者服務(wù),這里的 Java 類就是 ActivityThread
- handleParentProc() 進(jìn)行一些清理工作勿璃,不是本文的重點(diǎn)擒抛,略。