作为一名合格的 Android 开发,需要学习 Framework 知识,来解决 App 稳定性相关的问题
Framework 的源码学习一般由 init.rc 开始看起,因为它是一个 Android 系统启动必备的重要脚本,之后的几大系统进程都是由它启动的,比如 zygote,systemserver 等,这里主要记录一些基本概念,以及 Zygote 启动的源码分析
Binder 原理是相对较难的一个部分,先看其他系统源码,等功力足够时再拜读
init 启动的四个重要进程如下:
Zygote 进程启动时,会顺带启动 SystemServer 进程
fork 是通过 native 方法调用,返回 pid 给到 Java 层
负责安装卸载 app,主要用于解析 apk 文件等操作
我们都知道新开启的 App 进程都是由 Zygote.fork 出来的,那 fork 到底是个什么操作呢
首先 fork 是叉子的意思,我们所提及的 fork 实际为 native 层的 fork() 函数,当执行该函数时,会对父进程进行一次拷贝,拷贝完成过后,但用户内存空间是彼此独立,从此刻开始,开始各走各的
fork() 调用一次,返回两次,这是特性
AMS 通过 Socket 来通知 Zygote 进程,发送过程是怎样的,可以看下这篇文章 fork 进程的过程
AMS -> Zygote 通过 socket 请求,Zygote 调用 fork() 方法,成功后返回给 AMS,新进程创建后调用 AtivityThread.main()
全名是 EventPoll ,poll 是轮询的意思,是一个事件通知机制,性能上比较好,Handler 底层的事件唤醒也是用这玩意,具体是怎么实现的,不太清楚,先挖个坑,后面找个时间拜读一下源码
首先 Android 系统的第一个进程为 init 进程,负责解析执行 init.rc ,并且启动了 Zygote 进程
接下来通过阅读源码,分析一下 Zygote 的启动过程,从 AndroidRuntime,cpp 的 start() 开始看起
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
const char* rootDir = getenv("ANDROID_ROOT")
// 创建虚拟机
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
// 传入 ZygoteInit 的类路径
// 当前线程为虚拟机的主线程
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
}
}
//执行到这里虚拟机退出,应该对应着进程销毁
free(slashClassName);
ALOGD("Shutting down VM\n");
}
通过 native 创建了虚拟机实例,然后通过 JNI 调用 ZygoteInit ,开始到 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;
// 判断各种配置开关
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.");
}
//是否预加载(具体为预加载 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");
// 触发一次 gc (具体由 ZygoteHooks执行)
gcAndFinalize();
bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
bootTimingsTraceLog.traceEnd(); // ZygoteInit
Zygote.initNativeState(isPrimaryZygote);
ZygoteHooks.stopZygoteNoThreadCreation();
// ZygoteServer 做为 Socket 服务端,创建 socket 连接
zygoteServer = new ZygoteServer(isPrimaryZygote);
// 创建 SystemSerrver 进程,通过 Zygote fork 出来,之后 SystemSerrver 负责创建 AMS 等重要服务
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.
// 轮询执行,先不关注这块
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();
}
}
总结一下 Zygote 的启动过程: