前言
作為一名合格的 Android 開發(fā),需要學(xué)習(xí) Framework 知識,來解決 App 穩(wěn)定性相關(guān)的問題
Framework 的源碼學(xué)習(xí)一般由 init.rc 開始看起,因為它是一個 Android 系統(tǒng)啟動必備的重要腳本,之后的幾大系統(tǒng)進(jìn)程都是由它啟動的,比如 zygote,systemserver 等,這里主要記錄一些基本概念,以及 Zygote 啟動的源碼分析
Binder 原理是相對較難的一個部分,先看其他系統(tǒng)源碼,等功力足夠時再拜讀
init.rc
init 啟動的四個重要進(jìn)程如下:
- Zygote 創(chuàng)建 App 的進(jìn)程
- ServiceManager 負(fù)責(zé)c/s通信管理的進(jìn)程
- SurfaceFlingler 顯示渲染服務(wù)
- Media 多媒體服務(wù)
SystemServer
Zygote 進(jìn)程啟動時,會順帶啟動 SystemServer 進(jìn)程
fork 是通過 native 方法調(diào)用,返回 pid 給到 Java 層
PMS
負(fù)責(zé)安裝卸載 app收班,主要用于解析 apk 文件等操作
fork 進(jìn)程的理解
我們都知道新開啟的 App 進(jìn)程都是由 Zygote.fork 出來的祝旷,那 fork 到底是個什么操作呢
Zygote進(jìn)程和app進(jìn)程fork過程分析
首先 fork 是叉子的意思,我們所提及的 fork 實際為 native 層的 fork() 函數(shù),當(dāng)執(zhí)行該函數(shù)時,會對父進(jìn)程進(jìn)行一次拷貝,拷貝完成過后,但用戶內(nèi)存空間是彼此獨(dú)立,從此刻開始,開始各走各的
fork() 調(diào)用一次,返回兩次,這是特性
- AMS 和 Zygote 間是怎樣通信的
AMS 通過 Socket 來通知 Zygote 進(jìn)程坏挠,發(fā)送過程是怎樣的换况,可以看下這篇文章 fork 進(jìn)程的過程
AMS -> Zygote 通過 socket 請求缔御,Zygote 調(diào)用 fork() 方法朝氓,成功后返回給 AMS径荔,新進(jìn)程創(chuàng)建后調(diào)用 AtivityThread.main()
對于 epoll 的理解
全名是 EventPoll 垂寥,poll 是輪詢的意思颠黎,是一個事件通知機(jī)制另锋,性能上比較好,Handler 底層的事件喚醒也是用這玩意盏缤,具體是怎么實現(xiàn)的砰蠢,不太清楚,先挖個坑,后面找個時間拜讀一下源碼
Zygote 啟動過程
首先 Android 系統(tǒng)的第一個進(jìn)程為 init 進(jìn)程,負(fù)責(zé)解析執(zhí)行 init.rc ,并且啟動了 Zygote 進(jìn)程
接下來通過閱讀源碼,分析一下 Zygote 的啟動過程,從 AndroidRuntime,cpp 的 start() 開始看起
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
const char* rootDir = getenv("ANDROID_ROOT")
// 創(chuàng)建虛擬機(jī)
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
// 傳入 ZygoteInit 的類路徑
// 當(dāng)前線程為虛擬機(jī)的主線程
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
//執(zhí)行到這里虛擬機(jī)退出,應(yīng)該對應(yīng)著進(jìn)程銷毀
free(slashClassName);
ALOGD("Shutting down VM\n");
}
通過 native 創(chuàng)建了虛擬機(jī)實例,然后通過 JNI 調(diào)用 ZygoteInit ,開始到 Java 層的邏輯了
- Java 層
// ZygoteInit.class
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
// Zygote goes into its own process group.
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to setpgid(0,0)", ex);
}
Runnable caller;
try {
// 開啟 DDMMS
RuntimeInit.preForkInit();
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
// 判斷各種配置開關(guān)
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
// 判斷 SocketName 是否為 "zygote"
final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
if (!isRuntimeRestarted) {
if (isPrimaryZygote) {
FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START,
startTime);
}
// 判斷 SocketName 是否為 "zygote_secondary"
else if (zygoteSocketName.equals(Zygote.SECONDARY_SOCKET_NAME)) {
FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SECONDARY_ZYGOTE_INIT_START,
startTime);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
//是否預(yù)加載(具體為預(yù)加載 class / 類加載器 / 資源文件等)
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
}
// Do an initial gc to clean up after startup
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
// 觸發(fā)一次 gc (具體由 ZygoteHooks執(zhí)行)
gcAndFinalize();
bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
bootTimingsTraceLog.traceEnd(); // ZygoteInit
Zygote.initNativeState(isPrimaryZygote);
ZygoteHooks.stopZygoteNoThreadCreation();
// ZygoteServer 做為 Socket 服務(wù)端,創(chuàng)建 socket 連接
zygoteServer = new ZygoteServer(isPrimaryZygote);
// 創(chuàng)建 SystemSerrver 進(jìn)程,通過 Zygote fork 出來,之后 SystemSerrver 負(fù)責(zé)創(chuàng)建 AMS 等重要服務(wù)
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
// 輪詢執(zhí)行,先不關(guān)注這塊
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}
總結(jié)一下 Zygote 的啟動過程:
- 解析 init.rc 創(chuàng)建 AppRunTime
- 執(zhí)行 AndroidRuntime.Start()
- JNI 調(diào)用 ZygoteInit.main(),轉(zhuǎn)到 Java 層了
- 創(chuàng)建 Socket 服務(wù)端,準(zhǔn)備相應(yīng)客戶端的請求
- 預(yù)加載
- 通過 fork 的方式啟動 SystemServer 進(jìn)程
- 開啟輪詢