一、启动入口
在 Android 8.0 版本后, 对 init.rc 文件进行了拆分,每个服务对应一个 rc 文件。
- init.XXX.rc 文件:这里的 XXX 代指不同的服务,是多个非常重要的配置文件。该文件是由 Android 初始化语言 Android Init Language 编写的脚本。例如 Zygote 启动脚本在 init.zygoteXX.rc 中定义,XX 是处理器位数,例如 64 位处理器是 init.zygote64.rc 。
从 Android5.0 开始, Android 开始支持 64 位程序, Zygote 有了 32 和 64 位的区别, ro.zygote 的取值有以下四种:
- init.zygote32.rc :表示支持纯 32 位程序。
- init.zygote64.rc : 表示支持纯 64 位程序。
- init.zygote32_64.rc :表示即支持 32 位程序也支持 64 位程序;脚本中有两个 Service ,会启动两个 Zygote 进程:
- 一个名为 zygote,执行程序为 app_process32 ,作为主模式;
- 另一个名为 zygotę_secondary ,执行程序为 app_process64 ,作为辅模式。
- init.zygote64_32.rc:主模式与辅模式正好与 32_64 相反。
这里以zygote64_32.rc为例 源码如下: /system/core/rootdir/init.zygote64_32.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc reserved_disk
// 660 权限 只有拥有者有读写权限;而属组用户和其他用户只有读权限。
socket zygote stream 660 root system
socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
// 创建子进程时,向 /dev/cpuset/foreground/tasks 写入pid
writepid /dev/cpuset/foreground/tasks
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
class main
priority -20
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
socket usap_pool_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
上面的脚本大概的意思就是:
- 通过
Service
命令通知init
进程创建名为zygote
的进程,zygote进程对应的路径为system/bin/app_process64
。 - 启动的入口即是
class main
所指的main函数,而app_process64对应的代码定义在app_main.cpp
中。 - 后面的是要传给
app_process64
的参数。
二、app_main.cpp
frameworks/base/cmds/app_process/app_main.cpp
app_main.cpp
的 main
函数的重要流程:
int main(int argc, char* const argv[])
{
/* ... */
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
/* ... */
++i; // 跳过第一个参数(父目录)
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
// 如果main函数运行在Zygote进程中,则将zygote设置为true
zygote = true;
// 设置进程的名字
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
// 如果main函数运行在SystemServer进程中,则将startSystemServer设置为true
startSystemServer = true;
}
/* ... */
}
/* ... */
if (zygote) {
// 如果运行在Zygote进程中,则调用AppRuntime的start函数
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
重要流程概括:
-
判断当前 main函数是运行在 Zygote 进程还是 SystemServer 进程。
Zygote 进程通过 fock 自身来创建子进程,因此 Zygote 进程和它的子进程都可以进入
app_main.cpp
的main
函数, 所以main
函数中必须区分当前运行在哪个进程。 -
如果运行在 Zygote 进程中,则调用 AppRuntime 的
start
函数来启动 Java 虚拟机。而
AppRuntime
又继承于AndroidRuntime
,AppRuntime
中并没有重写父类的start()
方法,所以这里start()
方法调用的是AndroidRuntime
的start()
方法。
三、AndroidRuntime.cpp
frameworks/base/core/jni/AndroidRuntime.cpp
AndroidRuntime.cpp
的 start
函数的重要流程:
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
/* ... */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
// 创建Java虚拟机
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
// 对虚拟机进行初始化
onVmCreated(env);
// 为Java虚拟机注册JNI方法
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
/* ... */
// 从 app_main的main函数传递过来的className为com.android.internal.os.ZygoteInit
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i = 0; i < options.size(); ++i) {
jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
assert(optionsStr != NULL);
env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}
// 启动虚拟机,该线程成为虚拟机的主线程,直到虚拟机退出后才返回。
// 将className的“.”替换为“/”
char* slashClassName = toSlashClassName(className != NULL ? className : "");
// 查找ZygoteInit这个Java类
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
} else {
// 找到ZygoteInit的main方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
// 通过JNI调用ZygoteInit的main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
/* ... */
}
}
/* ... */
}
重要流程概括:
- 调用
startVm
函数来创建 Java 虚拟机。 - 调用
startReg
函数为 Java 虚拟机注册 JNI 方法。 - 将传递过来的参数
className
的值com.android.internal.os.ZygoteInit
中的.
替换为/
,即com/android/internal/os/ZygoteInit
,并赋值给slashClassName
。 - 根据
slashClassName
去查找Zygotelnit
类。 - 如果找到了,则通过 JNI 调用
ZygoteInit
的main
方法。
⭐️ 在此之前,一直在 native 层运行,没有任何代码进入 Java 框架层,也就是说是 Zygote 开启了 Java 框架层的运行。
四、ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
ZygoteInit.java
的 main
方法和 startSystemServer
方法的重要流程
不同版本,代码略有差别:
以下是 Android 8.0 中的 ZygoteInit
类。
public static void main(String argv[]) {
// 创建ZygoteServer对象
ZygoteServer zygoteServer = new ZygoteServer();
/* ... */
try {
/* ... */
String socketName = "zygote";
/* ... */
// 创建一个Server端的Socket,并传入socketName
zygoteServer.registerServerSocket(socketName);
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();
} else {
Zygote.resetNicePriority();
}
/* ... */
if (startSystemServer) {
// 启动SystemServer进程,并捕获Zygote.MethodAndArgsCaller异常
startSystemServer(abiList, socketName, zygoteServer);
}
Log.i(TAG, "Accepting command socket connections");
// 等待AMS创建新应用程序进程的请求
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
// SystemServer进程完成初始化,调用run方法
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
/* ... */
// 创建args数组,保存启动SystemServer的启动参数
String args[] = {
"--setuid=1000", // 用户id
"--setgid=1000", // 用户组id
// 进程拥有的权限
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server", // 进程名
"--runtime-args",
// 启动的类名
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
// 将args数组封装成Arguments对象
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
// 创建一个子进程,即SystemServer进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
// 当前代码逻辑运行在子进程中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
// 关闭Zygote进程创建的Socket
zygoteServer.closeServerSocket();
// 处理SystemServer进程
handleSystemServerProcess(parsedArgs);
}
return true;
}
重要流程概括:
- 通过
registerServerSocket
方法创建一个 Server 端名为zygote
的 Socket 对象,并通过runSelectLoop
方法无限循环等待ActivityManagerService
的请求,一旦有请求,则调用ZygoteConnection
的runOnce
函数来创建一个新的应用程序进程。 - 预加载公共类和公共资源,而这些资源可以通过 fork 的方式,共享给它的全部子进程。
- 启动 SystemServer 进程。