由于本人能力有限,所考虑或者疏忽错漏的地方或多或少应该存在。同时,Android从启动过程开始,实际上就涉及多个技术难点和多种通信机制的知识点。
基于上面两个原因,笔者会一直修改,补充,拓展此文。希望能够坚持下去,从而真正达到触类旁通。
从我们长按手机电源键,到安卓系统完全启动之间,总共经历了以下五个阶段。
第一步:启动电源以及系统启动
当电源按下,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM,然后执行。
第二步:引导程序
引导程序是在Android操作系统开始运行前的一个小程序。引导程序是运行的第一个程序,因此它是针对特定的主板与芯片的。设备制造商要么使用很受欢迎的引导程序比如redboot、uboot、qi bootloader或者开发自己的引导程序,它不是Android操作系统的一部分。引导程序是OEM厂商或者运营商加锁和限制的地方。
引导程序分两个阶段执行。第一个阶段,检测外部的RAM以及加载对第二阶段有用的程序;第二阶段,引导程序设置网络、内存等等。这些对于运行内核是必要的,为了达到特殊的目标,引导程序可以根据配置参数或者输入数据设置内核。
第三步:内核的启动
Android内核与桌面Linux内核启动的方式差不多。内核启动时,设置缓存、被保护存储器、计划列表,加载驱动。当内核完成系统设置,它首先在系统文件中寻找”init”文件,然后启动init进程。
第四步:init进程的启动
init是第一个进程,我们可以说它是root进程或者说有进程的父进程。init进程将进行两个主要操作,一是挂载目录,比如/sys、/dev、/proc,二是运行init.rc脚本。
其实第一步到第三步,可以理解为是一个Linux内核的启动的过程。从第四步开始,Android系统才可以算作是“真正”的开始启动。这也是本文所关注的重点起始的地方。先从init.rc脚本开始讲起。
.rc文件是安卓初始化语言,有特定的格式以及规则。例如:
- service <name><pathname> [<argument>]*
- <option>
- <option>
- ...
如上所示,这个语法代表的是启动一个指定路径的服务。
在init.rc这个配置文件中,涉及到两个最关键的步骤:
(init.rc文件既可在源码目录/system/core/rootdir,也可在设备根目录下找到)
1.启动ServiceManager进程
- service servicemanager /system/bin/servicemanager
ServiceManager是Binder的服务管理守护进程,是Binder的核心,由其使用Binder驱动进行IPC管理,关于IPC通讯 的机制,此处暂不详述。在APP和Framework中,应用程序使用的ServiceManager.Java就是通过Proxy与这个守护进程进行的 通讯。
2. 启动Zygote进程,Zygote的中文翻译是受精卵或孵化器,顾名思义,从它开始将会衍生出Android系统中的各种子进程。
- service zygote /system/bin/app_process -Xzygote/system/bin --zygote --start-system-server
第五阶段:Zygote进程加载SystemServer进程,并启动系统服务
如果在init.rc文件中找不到这一语句,我们可以关注下init.rc文件开头的几行import代码。
- import/init.environ.rc
- import /init.usb.rc
- import /init.${ro.hardware}.rc
- import /init.${ro.zygote}.rc //在同一目录下,可以找到类似于init.zygote32.rc的文件
- //不同名字的zygote进程启动文件对应于不同位数的设备
- import /init.trace.rc
随便打开一个init.zygote32.rc文件,即可找到此语句
在这个步骤中,将启动zygote服务进程。Zygote进程将成为所有应用进程的孵化器。
我们来看一下app_process的代码,位置是在:
frameworks/base/cmds/app_process/app_main.cpp
C++文件的执行入口总在main()函数当中——其入口函数main在文件app_main.cpp中,接下来我们就从这个main函数入手来分析zygote的内部逻辑。
/*启动zygote的方式为service zygote /system/bin/app_process-Xzygote /system/bin --zygote --start-system-server
* 所以 argc == 5, argv中存的就是这5个参数argv[0]=="/system/bin/app_process" ,argv[1]== "-Xzygote"....
*/
- int main(int argc, char* const argv[])
- {
- if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
- // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return
- // EINVAL. Don't die on such kernels.
- if (errno != EINVAL) {
- LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
- return 12;
- }
- }
- AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
- // Process command line arguments
- // ignore argv[0]
- argc--;
- argv++;
- // Everything up to '--' or first non '-' arg goes to the vm.
- //
- // The first argument after the VM args is the "parent dir", which
- // is currently unused.
- //
- // After the parent dir, we expect one or more the following internal
- // arguments :
- //
- // --zygote : Start in zygote mode
- // --start-system-server : Start the system server.
- // --application : Start in application (stand alone, non zygote) mode.
- // --nice-name : The nice name for this process.
- //
- // For non zygote starts, these arguments will be followed by
- // the main class name. All remaining arguments are passed to
- // the main method of this class.
- //
- // For zygote starts, all remaining arguments are passed to the zygote.
- // main function.
- //
- // Note that we must copy argument string values since we will rewrite the
- // entire argument block when we apply the nice name to argv0.
- int i;
- for (i = 0; i < argc; i++) {
- if (argv[i][0] != '-') {
- break;
- }
- if (argv[i][1] == '-' && argv[i][2] == 0) {
- ++i; // Skip --.
- break;
- }
- runtime.addOption(strdup(argv[i]));
- }
- // Parse runtime arguments. Stop at first unrecognized option.
- bool zygote = false;
- bool startSystemServer = false;
- bool application = false;
- String8 niceName;
- String8 className;
- ++i; // Skip unused "parent dir" argument.
- while (i < argc) {
- const char* arg = argv[i++];
- if (strcmp(arg, "--zygote") == 0) { //将会走这个分支
- zygote = true;
- niceName = ZYGOTE_NICE_NAME;
- } else if (strcmp(arg, "--start-system-server") == 0) { //将会走这个分支
- startSystemServer = true;
- } else if (strcmp(arg, "--application") == 0) {
- application = true;
- } else if (strncmp(arg, "--nice-name=", 12) == 0) {
- niceName.setTo(arg + 12);
- } else if (strncmp(arg, "--", 2) != 0) { //启动zygote中的参数都不会走到这个分支,仔细思考下就知道是因为所有带"--"的参数都会先被前面的if判断分支截获
- className.setTo(arg);
- break;
- } else {
- --i;
- break;
- }
- }
- //经历了上面的while循环后,总结下变量的赋值和变化情况:
- //boolean zygote 变为true
- //boolean startSystemServer变为true
- //boolean application依然为false
- //字符串变量niceName和className为Null
- //在这个基础上分析下面的流程就很容易了
- Vector<String8> args; //重点关注下这个变量,它将作为接下来调用runtime.start()方法的传入参数
- if (!className.isEmpty()) {
- // We're not in zygote mode, the only argument we need to pass
- // to RuntimeInit is the application argument.
- //
- // The Remainder of args get passed to startup class main(). Make
- // copies of them before we overwrite them with the process name.
- args.add(application ? String8("application") : String8("tool"));
- runtime.setClassNameAndArgs(className, argc - i, argv + i);
- } else {
- // We're in zygote mode.
- maybeCreateDalvikCache();
- if (startSystemServer) {
- args.add(String8("start-system-server")); //args中添加的第一个变量
- }
- char prop[PROP_VALUE_MAX];
- if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
- LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
- ABI_LIST_PROPERTY);
- return 11;
- }
- String8 abiFlag("--abi-list=");
- abiFlag.append(prop);
- args.add(abiFlag); //args中添加的第二个变量
- // In zygote mode, pass all remaining arguments to the zygote
- // main() method.
- for (; i < argc; ++i) {
- args.add(String8(argv[i]));
- }
- }
- if (!niceName.isEmpty()) {
- runtime.setArgv0(niceName.string());
- set_process_name(niceName.string());
- }
- if (zygote) {
- runtime.start("com.android.internal.os.ZygoteInit", args); //zygote为true
- } else if (className) {
- runtime.start("com.android.internal.os.RuntimeInit", args);
- } else {
- fprintf(stderr, "Error: no class name or --zygote supplied.\n");
- app_usage();
- LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
- return 10;
- }
- }
在执行到app_process/app_main.cpp这个文件的最后,将会调用runtime.start("com.android.internal.os.ZygoteInit",args); 这个语句runtime是一个AppRuntime变量,其定义同样在/frameworks/base/cmds/app_process/app_main.cpp这个文件当中。
- class AppRuntime : public AndroidRuntime
- ......
- ;
可以发现其继承于AndroidRuntime类。AndroidRuntime类定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中。
runtime.start方法调用的正是其父类AndroidRuntime.cpp中的start方法。
AndroidRuntime.start()方法代码如下:
- /*
- * Start the Android runtime. This involves starting the virtual machine
- * and calling the "static void main(String[] args)" method in the class
- * named by "className".
- *
- * Passes the main function two arguments, the class name and the specified
- * options string.
- */
- void AndroidRuntime::start(const char* className, const Vector<String8>& options)
- {
- ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
- className != NULL ? className : "(unknown)");
- static const String8 startSystemServer("start-system-server");
- /*
- * 'startSystemServer == true' means runtime is obsolete and not run from
- * init.rc anymore, so we print out the boot start event here.
- */
- for (size_t i = 0; i < options.size(); ++i) {
- if (options[i] == startSystemServer) {
- /* track our progress through the boot sequence */
- const int LOG_BOOT_PROGRESS_START = 3000;
- LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
- }
- }
- const char* rootDir = getenv("ANDROID_ROOT");
- if (rootDir == NULL) {
- rootDir = "/system";
- if (!hasDir("/system")) {
- LOG_FATAL("No root directory specified, and /android does not exist.");
- return;
- }
- setenv("ANDROID_ROOT", rootDir, 1);
- }
- //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
- //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
- /* start the virtual machine */
- JniInvocation jni_invocation;
- jni_invocation.Init(NULL);
- JNIEnv* env;
- if (startVm(&mJavaVM, &env) != 0) { //关键步骤1,开启虚拟机
- return;
- }
- onVmCreated(env);
- /*
- * Register android functions. //关键步骤2,注册JNI方法
- */
- if (startReg(env) < 0) {
- ALOGE("Unable to register all android natives\n");
- return;
- }
- /*
- * We want to call main() with a String array with arguments in it.
- * At present we have two arguments, the class name and an option string.
- * Create an array to hold them.
- */
- 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);
- }
- /*
- * Start VM. This thread becomes the main thread of the VM, and will
- * not return until the VM exits. //关键步骤3
- */
- char* slashClassName = toSlashClassName(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 {
- env->CallStaticVoidMethod(startClass, startMeth, strArray); //调用其main方法
- #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");
- }
关键步骤1——调用函数startVM,启动虚拟机
关键步骤2——调用函数startReg注册JNI方法,以完成安卓上层和native层的交互
关键步骤3——找到className为” com.android.internal.os.ZygoteInit”的类,并调用其main方法
接着前行,步骤3中涉及到这个类定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中。找到其函数入口main方法:
- public static void main(String argv[]) {
- try {
- // Start profiling the zygote initialization.
- SamplingProfilerIntegration.start();
- boolean startSystemServer = false;
- String socketName = "zygote";
- String abiList = null;
- for (int i = 1; i < argv.length; i++) {
- if ("start-system-server".equals(argv[i])) {
- startSystemServer = 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)) {
- socketName = argv[i].substring(SOCKET_NAME_ARG.length());
- } else {
- throw new RuntimeException("Unknown command line argument: " + argv[i]);
- }
- }
- if (abiList == null) {
- throw new RuntimeException("No ABI list supplied.");
- }
- registerZygoteSocket(socketName); //关键步骤1,注册Zygote进程的套接字
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
- SystemClock.uptimeMillis());
- preload();
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
- SystemClock.uptimeMillis());
- // Finish profiling the zygote initialization.
- SamplingProfilerIntegration.writeZygoteSnapshot();
- // Do an initial gc to clean up after startup
- gc();
- // Disable tracing so that forked processes do not inherit stale tracing tags from
- // Zygote.
- Trace.setTracingEnabled(false);
- if (startSystemServer) {
- startSystemServer(abiList, socketName);//关键步骤2,启动SystemServer
- }
- Log.i(TAG, "Accepting command socket connections");
- runSelectLoop(abiList);//关键步骤3
- closeServerSocket();
- } catch (MethodAndArgsCaller caller) {
- caller.run();
- } catch (RuntimeException ex) {
- Log.e(TAG, "Zygote died with exception", ex);
- closeServerSocket();
- throw ex;
- }
- }
详细分析这四个关键步骤。
关键步骤1:——调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService通讯
- ZygoteInit.registerZygoteSocket():
- /**
- * Registers a server socket for zygote command connections
- *
- * @throws RuntimeException when open fails
- */
- private static void registerZygoteSocket(String socketName) {
- if (sServerSocket == null) {
- int fileDesc;
- final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; //安卓规范套接字前缀+socket名字
- try {
- String env = System.getenv(fullSocketName);
- fileDesc = Integer.parseInt(env);
- } catch (RuntimeException ex) {
- throw new RuntimeException(fullSocketName + " unset or invalid", ex);
- }
- try {
- sServerSocket = new LocalServerSocket(
- createFileDescriptor(fileDesc));//创建一个文件描述符
- } catch (IOException ex) {
- throw new RuntimeException(
- "Error binding to local socket '" + fileDesc + "'", ex);
- }
- }
- }
关键步骤2:——调用startSystemServer,启动SystemServer这个系统核心进程
startSystemServer方法位于同一文件ZygoteInit.java当中。
- ZygoteInit.startSystemServer():
- /**
- * Prepare the arguments and fork for the system server process.
- */
- private static boolean startSystemServer(String abiList, String socketName)
- throws MethodAndArgsCaller, RuntimeException {
- long capabilities = posixCapabilitiesAsBits(
- OsConstants.CAP_BLOCK_SUSPEND,
- OsConstants.CAP_KILL,
- OsConstants.CAP_NET_ADMIN,
- OsConstants.CAP_NET_BIND_SERVICE,
- OsConstants.CAP_NET_BROADCAST,
- OsConstants.CAP_NET_RAW,
- OsConstants.CAP_SYS_MODULE,
- OsConstants.CAP_SYS_NICE,
- OsConstants.CAP_SYS_RESOURCE,
- OsConstants.CAP_SYS_TIME,
- OsConstants.CAP_SYS_TTY_CONFIG
- );
- /* 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,1032,3001,3002,3003,3006,3007",
- "--capabilities=" + capabilities + "," + capabilities,
- "--runtime-init",
- "--nice-name=system_server",
- "com.android.server.SystemServer",
- };
- ZygoteConnection.Arguments parsedArgs = null;
- int pid;
- try {
- parsedArgs = new ZygoteConnection.Arguments(args);
- ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
- ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
- /* Request to fork the system server process */
- pid = Zygote.forkSystemServer( //与Android 4.4之前的版本不一样的地方
- parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids,
- parsedArgs.debugFlags,
- null,
- parsedArgs.permittedCapabilities,
- parsedArgs.effectiveCapabilities);
- } catch (IllegalArgumentException ex) {
- throw new RuntimeException(ex);
- }
- /* For child process */
- if (pid == 0) {
- if (hasSecondZygote(abiList)) {
- waitForSecondaryZygote(socketName);
- }
- handleSystemServerProcess(parsedArgs);
- }
- return true;
- }
这里我们可以看到,Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。
- ZygoteInit.handleSystemServerProcess():
- /**
- * Finish remaining work for the newly forked system server process.
- */
- private static void handleSystemServerProcess(
- ZygoteConnection.Arguments parsedArgs)
- throws ZygoteInit.MethodAndArgsCaller {
- closeServerSocket();
- // set umask to 0077 so new files and directories will default to owner-only permissions.
- Os.umask(S_IRWXG | S_IRWXO);
- if (parsedArgs.niceName != null) {
- Process.setArgV0(parsedArgs.niceName);
- }
- final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
- if (systemServerClasspath != null) {
- performSystemServerDexOpt(systemServerClasspath);
- }
- if (parsedArgs.invokeWith != null) {
- String[] args = parsedArgs.remainingArgs;
- // If we have a non-null system server class path, we'll have to duplicate the
- // existing arguments and append the classpath to it. ART will handle the classpath
- // correctly when we exec a new process.
- if (systemServerClasspath != null) {
- String[] amendedArgs = new String[args.length + 2];
- amendedArgs[0] = "-cp";
- amendedArgs[1] = systemServerClasspath;
- System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
- }
- WrapperInit.execApplication(parsedArgs.invokeWith,
- parsedArgs.niceName, parsedArgs.targetSdkVersion,
- null, args);
- } else {
- ClassLoader cl = null;
- if (systemServerClasspath != null) {
- cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
- Thread.currentThread().setContextClassLoader(cl);
- }
- /*
- * Pass the remaining arguments to SystemServer.
- */
- RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
- }
- /* should never reach here */
- }
这个函数接着调用RuntimeInit.zygoteInit函数来进一步执行启动SystemServer组件的操作。
- RuntimeInit.zygoteInit函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中。
- public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
- throws ZygoteInit.MethodAndArgsCaller {
- if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
- redirectLogStreams();
- commonInit();
- nativeZygoteInit(); //调用了JNI层的方法,为Binder通信机制的建立奠定了基础,此处暂不深入讨论
- applicationInit(targetSdkVersion, argv, classLoader);
- }
继续查看RuntimeInit.applicationInit()方法
- private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
- throws ZygoteInit.MethodAndArgsCaller {
- // If the application calls System.exit(), terminate the process
- // immediately without running any shutdown hooks. It is not possible to
- // shutdown an Android application gracefully. Among other things, the
- // Android runtime shutdown hooks close the Binder driver, which can cause
- // leftover running threads to crash before the process actually exits.
- nativeSetExitWithoutCleanup(true);
- // We want to be fairly aggressive about heap utilization, to avoid
- // holding on to a lot of memory that isn't needed.
- VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
- VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
- final Arguments args;
- try {
- args = new Arguments(argv);
- } catch (IllegalArgumentException ex) {
- Slog.e(TAG, ex.getMessage());
- // let the process exit
- return;
- }
- // Remaining arguments are passed to the start class's static main
- /*
- *从ZygoteInit.startSystemServer()方法中传过来的parsedArgs参数包括
- *"--nice-name=system_server", "com.android.server.SystemServer"
- *实际上它们就是互相对应的硬编码,调用SystemServer的main方法
- */
- invokeStaticMain(args.startClass, args.startArgs, classLoader);
- }
- }
不要放弃,继续往下看,到这里我们将调用RuntimeInit.java中的invokeStaticMain方法:
- /**
- * Invokes a static "main(argv[]) method on class "className".
- * Converts various failing exceptions into RuntimeExceptions, with
- * the assumption that they will then cause the VM instance to exit.
- *
- * @param className Fully-qualified class name
- * @param argv Argument vector for main()
- * @param classLoader the classLoader to load {@className} with
- */
- private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
- throws ZygoteInit.MethodAndArgsCaller {
- Class<?> cl;
- try {
- cl = Class.forName(className, true, classLoader);//加载com.android.server.SystemServer这个类
- } 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 });//获取main方法
- } 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.
- */
- throw new ZygoteInit.MethodAndArgsCaller(m, argv);
- }
我们出奇的发现RuntimeInit.invokeStaticMain方法并没有直接调用SystemServer的main的方法,那么它是怎么被调用的?答案在这个函数的末尾——抛出了一个MethodAndArgsCaller异常。源码中注释非常清楚地说明了,这个异常将在main方法中被截获。
- public static void main(String argv[]) {
- try {
- ........ //省略掉中间的内容
- } catch (MethodAndArgsCaller caller) {//就是在这里截获的!
- caller.run();
- } catch(RuntimeException ex) {
- Log.e(TAG, "Zygote died withexception", ex);
- closeServerSocket();
- throw ex;
- }
- }
目光转移到MethodAndArgsCaller的run()方法。该方法定义在/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java方法中。
- public static class MethodAndArgsCaller extends Exception
- implements Runnable {
- /** method to call */
- private final Method mMethod;
- /** argument array */
- private final String[] mArgs;
- public MethodAndArgsCaller(Method method, String[] args) {
- //将方法参数,和调用方法的类传递下来
- mMethod = method;
- mArgs = args;
- }
- public void run() {
- try {
- //在线程的run()方法中开始正式调用main方法
- mMethod.invoke(null, new Object[] { mArgs });
- } catch (IllegalAccessException ex) {
- throw new RuntimeException(ex);
- } catch (InvocationTargetException ex) {
- Throwable cause = ex.getCause();
- if (cause instanceof RuntimeException) {
- throw (RuntimeException) cause;
- } else if (cause instanceof Error) {
- throw (Error) cause;
- }
- throw new RuntimeException(ex);
- }
- }
- }
至此,终于正式调用SystemServer的main方法了。
Android5.0.0以上版本的SystemServer.java文件位于
/frameworks/base/services/java/com/android/server/中
- public static void main(String[] args) {
- new SystemServer().run();
- }
- public SystemServer() {
- // Checkfor factory test mode.
- mFactoryTestMode = FactoryTest.getMode();
- }
- private void run() {
- // If a device's clock is before 1970 (before 0), a lot of
- // APIs crash dealing with negative numbers, notably
- // java.io.File#setLastModified, so instead we fake it and
- // hope that time from cell towers or NTP fixes it shortly.
- if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
- Slog.w(TAG, "System clock is before 1970; setting to 1970.");
- SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
- }
- // Here we go!
- Slog.i(TAG, "Entered the Android system server!");
- EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
- // In case the runtime switched since last boot (such as when
- // the old runtime was removed in an OTA), set the system
- // property so that it is in sync. We can't do this in
- // libnativehelper's JniInvocation::Init code where we already
- // had to fallback to a different runtime because it is
- // running as root and we need to be the system user to set
- // the property. http://b/11463182
- SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
- // Enable the sampling profiler.
- if (SamplingProfilerIntegration.isEnabled()) {
- SamplingProfilerIntegration.start();
- mProfilerSnapshotTimer = new Timer();
- mProfilerSnapshotTimer.schedule(new TimerTask() {
- @Override
- public void run() {
- SamplingProfilerIntegration.writeSnapshot("system_server", null);
- }
- }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
- }
- // Mmmmmm... more memory!
- VMRuntime.getRuntime().clearGrowthLimit();
- // The system server has to run all of the time, so it needs to be
- // as efficient as possible with its memory usage.
- VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
- // Some devices rely on runtime fingerprint generation, so make sure
- // we've defined it before booting further.
- Build.ensureFingerprintProperty();
- // Within the system server, it is an error to access Environment paths without
- // explicitly specifying a user.
- Environment.setUserRequired(true);
- // Ensure binder calls into the system always run at foreground priority.
- BinderInternal.disableBackgroundScheduling(true);
- // Prepare the main looper thread (this thread).
- android.os.Process.setThreadPriority(
- android.os.Process.THREAD_PRIORITY_FOREGROUND);
- android.os.Process.setCanSelfBackground(false);
- Looper.prepareMainLooper();
- // Initialize native services.
- //关键步骤1
- System.loadLibrary("android_servers");
- nativeInit();
- // Check whether we failed to shut down last time we tried.
- // This call may not return.
- performPendingShutdown();
- // Initialize the system context.
- createSystemContext();
- //关键步骤2
- // Create the system service manager.
- mSystemServiceManager = new SystemServiceManager(mSystemContext);
- LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
- //关键步骤3
- // Start services.
- try {
- startBootstrapServices();
- startCoreServices();
- startOtherServices();
- } catch (Throwable ex) {
- Slog.e("System", "******************************************");
- Slog.e("System", "************ Failure starting system services", ex);
- throw ex;
- }
- // For debug builds, log event loop stalls to dropbox for analysis.
- if (StrictMode.conditionallyEnableDebugLogging()) {
- Slog.i(TAG, "Enabled StrictMode for system server main thread.");
- }
- // Loop forever.
- Looper.loop();
- throw new RuntimeException("Main thread loop unexpectedly exited");
- }
SystemServer.run()方法中最值得关注的就是我注释中标注的三个关键步骤,下面稍作解释:
关键步骤1——初始化native层的系统服务。从nativeInit名字就可以看出来这是一个native层的代码,调用了jni层的代码。这个方法的实际实现在:frameworks/base/services/core/jni/com_android_server_SystemServer.cpp。相关代码如下:
- </pre><pre name="code" class="cpp">static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) {
- char propBuf[PROPERTY_VALUE_MAX];
- property_get("system_init.startsensorservice", propBuf, "1");
- if (strcmp(propBuf, "1") == 0) {
- // Start the sensor service
- SensorService::instantiate();
- }
- }
大概就是根据属性配置文件来确定是否需要初始化SensorService,这里就不多介绍了。
关键步骤2——将SystemManagerService注册到SystemServer(自身)中。
关键步骤3——启动系统运行所需的服务。其中:
startBootstrapServices()方法启动ActivityManagerService(AMS),PowerManagerService,PackageManagerServices(),DisplayManagerService等系统关键服务。
startCoreServices()方法调用了一些核心服务,例如LightService,BatteryService等。
startOtherServices()方法则调用剩余的一些服务。出人意料的是,WindowMangaerService竟然是在这里启动。除此之外,还有InputManagerService和AlarmManagerService都在这里启动。
完成了这三个关键步骤后,最后会通过Looper.loop()来进行消息循环,然后处理消息。
此前安卓版本与5.0之后版本SystemServer的启动方式有很大区别:
此前的SystemServer会通过 ServerThread thr = new ServerThread();直接建立一个ServerThread进程。
到这里,系统的关键服务都启动完毕,安卓系统的启动过程也接近尾声。
这里执行完成后,层层返回,最后回到上面的ZygoteInit.main函数中,接下来它就要调用runSelectLoop函数进入一个无限循环在前面ZygoteInit.main函数关键步骤1中创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程了。runSelectLoop()函数实际上是在一死循环中利用zygoteConnection类通过socket的方式进行消息 处理,用于fork出新的zygote,从而以最轻量级的方式实现每个进程一个虚拟机的机制。
最后我们再简单梳理下Android启动的过程。毕竟这么复杂的过程需要不断回顾。后续可能会补充上更多流程图,以帮助自己和大家进行梳理。
1. Linux内核启动完毕后,系统开始init.rc配置文件启动Zygote进程。
2. Zygote进程的启动经历了ZygoteInit,RuntimeInit,fork出SystemServer这个进程。
3. SystemServer进程负责启动,初始化系统的关键服务,如包管理服务PackageManagerService和应用程序组件管理服务ActivityManagerService。除了注册到ServiceManager中,还将调用各服务的systemReady()告诉它们系统已经正常启动
4. (老罗总结)当我们需要启动一个Android应用程序时,ActivityManagerService会通过Socket进程间通信机制,通知Zygote进程为这个应用程序创建一个新的进程。
文末感谢下为我提供过帮助的博客大牛和文章,传送门:
1.《Android启动过程深入解析》我所归纳的安卓启动分为几个阶段由此文借鉴。
2.《Android系统进程Zygote启动过程的源代码分析》 安卓名人老罗的传世名作。
3. 《Android情景分析之深入解析system_server》为我解决了不少疑惑。