type
status
date
slug
summary
tags
category
icon
password
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调用执行ZygoteInitmain()方法
虚拟机是如何启动的,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驱动
  • 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中的一序列操作了.

总结

  1. Zygote进程的入口其实在ZygoteInit中;
  1. Zygote进程是通过app_process进程启动的
  1. zygote fork出其他进程依赖了localsocket + fd的机制
  1. 在启动Zygote进程之前,会先启动虚拟机,然后注册一些Native/JNI方法
  1. Android中每个进程都只有一个虚拟机,每个线程代表了着一个JNIEnv
  1. Zygote可以说是第一个Java进程
  1. system_server进程严格意义上并不是zygote主动启动的,而是创建zygote进程的过程中,一起fork出来的,只不过是zygote fork的.
Android系统启动流程分析Android系统启动流程-SystemServer分析
姜康
姜康
一个软件工程师
公告
type
status
date
slug
summary
tags
category
icon
password
🎉博客网站重新制作了🎉
👏欢迎更新体验👏