zygote是通过app_process或者app_process64命令行程序启动的.
先来看下app_process的流程:
app_process
int main(int argc, char* const argv[])
{
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
if (zygote) {
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.");
}
}
strdup():返回一个字符串指针,指向新复制的字符串
int strncmp ( const char * str1, const char * str2, size_t n ): 比较两个字符串的前n个字符,如果相等,则返回0
app_process 根据传入参数不同分为两种模式:
zygote模式,用于启动zygote进程
传入–zygote非zygote模式,用于启动普通的java程序
比如常用的adb shell 下的命令,如am,monkey,appwidget等:#!/system/bin/sh if [ "$1" != "instrument" ] ; then cmd activity "$@" else base=/system export CLASSPATH=$base/framework/am.jar exec app_process $base/bin com.android.commands.am.Am "$@" fi
系统启动的时候,我们分析zygote模式.
实际上不管哪个模式,都会执行AndroidRuntime::start()
方法,区别是传入的启动类不同:
AndroidRuntime
JavaVM* AndroidRuntime::mJavaVM = NULL;
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
/* 启动虚拟机 */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
/*
* 注册Android Native JNI方法
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
/*
* 找到要启动的类,执行它的main()方法
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
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);
}
/*
* 当前线程是VM的主线程,当VM销毁时线程才会退出
*/
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
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 {
// 这里是真实调用main()方法的地方
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
ALOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK)
ALOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
ALOGW("Warning: VM did not shut down cleanly\n");
}
AndroidRuntime启动过程主要做了三件事:
- 启动Android虚拟机,即ART Runtime
- 注册一些内置的Native方法(JNI)
- 通过JNI调用执行
ZygoteInit
的main()
方法
虚拟机是如何启动的,Native方法是如何注册的,这里暂时不分析,重点关注Zygote进程的启动.
ZygoteInit#main()
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
// 用程序自己的进程id和进程组id
Os.setpgid(0, 0);
Runnable caller;
try {
if (!enableLazyPreload) {
preload(bootTimingsTraceLog);
}
gcAndFinalize();
Zygote.initNativeState(isPrimaryZygote);
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
// 为fork system_server进程初始化一些参数
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// zygote进程中r== null,不会执行下面的代码
// system_server 进程r != null,会执行下面的代码
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();
}
}
这里主要做以下几件事:
- 创建ZygoteServer,利用local socket + file descriptor 机制响应应用的fork请求
- 预加载一些jar包中的class,classloader,一诶Android资源,共享库,图形驱动等
- 启动完之后运行几次GC清理下资源
- 从Zygote进程中使用fork方式创建system server进程
Local socket + fd 这一套机制暂时还不熟悉,后面再总结一下.
预加载的有以下内容:
/system/etc/preloaded-classes 文件中记录的类
包括Android Framework中的类,通过
Class.forName(className,true,null)
加载缓存一些非启动类的classloader
比如HIDL和Android test相关的
公共资源,让所有进程可以共享
com.android.internal.R.array.preloaded_drawables 中的内容
com.android.internal.R.array.preloaded_color_state_lists
com.android.internal.R.bool.config_freeformWindowManagement
HAL库
图像库驱动,比如OpenGL 或者 Vulkan驱动
加载共享的动态库
- libandroid.so
- libcompiler_rt.so
- libjnigraphics.so
TextView的字体资源
WebView相关的so库,libwebviewchromium_loader.so
创建system_server进程
在ZygoteInit##forSystemServer方法中:
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
int pid;
try {
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* system_server进程执行 */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
可以看到首先会初始化一些参数,比如uid,gid等.然后从Zygote进程利用fork方式创建system_server进程:
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
// Set the Java Language thread priority to the default value for new apps.
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
ZygoteHooks.postForkCommon();
return pid;
}
其中的native方式是一个JNI调用,源码在frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
中,所使用的还是localsocket + fd的那一套机制.
在system_server 创建成功之后,会执行handleSystemServerProcess
方法:
/**
* Finish remaining work for the newly forked system server process.
*/
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
// set umask to 0077 so new files and directories will default to owner-only permissions.
Os.umask(S_IRWXG | S_IRWXO);
// 设置进程名为system_server
if (parsedArgs.mNiceName != null) {
Process.setArgV0(parsedArgs.mNiceName);
}
// /system/framework 下面的jar包
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
//为这些jar执行dex opt,加快执行速度
performSystemServerDexOpt(systemServerClasspath);
}
if (parsedArgs.mInvokeWith != null) {
// 使用app_process64去执行命令:使用app_process64启动nicename进程
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
// 为哪些jar中的class创建PathClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
/* should never reach here */
}
这里会设置进程的名字,dex opt 一些system_server相关的jar,并设置PathClassLoader,最终会执行到RuntimeInit中,并找到
SystemServer.java的main方法,并执行:
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/*
* 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.
*/
return new MethodAndArgsCaller(m, argv);
}
到这个时候system_server进程已经创建完毕,后面开始执行SystemServer中的一序列操作了.
总结
- Zygote进程的入口其实在ZygoteInit中;
- Zygote进程是通过app_process进程启动的
- zygote fork出其他进程依赖了localsocket + fd的机制
- 在启动Zygote进程之前,会先启动虚拟机,然后注册一些Native/JNI方法
- Android中每个进程都只有一个虚拟机,每个线程代表了着一个JNIEnv
- Zygote可以说是第一个Java进程
- system_server进程严格意义上并不是zygote主动启动的,而是创建zygote进程的过程中,一起fork出来的,只不过是zygote fork的.