Android启动流程分析(十一) zygote的启动
来源:互联网 发布:算法第四版英文版pdf 编辑:程序博客网 时间:2024/06/06 04:51
#############################################
本文为极度寒冰原创,转载请注明出处
#############################################
前面的文章花了很大的篇幅去介绍了init进程如何去解析init.rc,如何去执行系统的一些服务。
那么,我们所说的zygote是怎么启动的呢?zygote又是具体负责了哪些工作呢?
本文我们来一探究竟。
zygote在inir.rc中有如下的描述:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd我们可以简单的分析下这两句话,
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
这个是说,zygote是属于main的class。
zygote是一个服务,服务的名字叫zygote. 启动的时候执行的命令是app_process, 传递的参数是-Xzygote /system/bin --zygote --start-system-server
那么,按照我们前面分析的理论,我们去看一下app_process是个什么东西
首先我们到framework的目录下,在base/cmds/app_process里面,我们看到了生成app_process的makefile
include $(CLEAR_VARS)LOCAL_SRC_FILES:= \ app_main.cppLOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ liblog \ libbinder \ libandroid_runtimeLOCAL_MODULE:= app_processLOCAL_MULTILIB := bothLOCAL_MODULE_STEM_32 := app_process32LOCAL_MODULE_STEM_64 := app_process64include $(BUILD_EXECUTABLE)我们可以看到app_process被执行生成了一个应用程序。
试想一下,zygote的这个服务应该是一直在运行的,但是我们如果adb shell去看ps的话,并找不到app_process的这个命令在一直运行。
这个是为什么呢?
首先我们从app_process的main函数里面截取出来一段
while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { // 如果从init.rc里面传进来的参数是带--zygote的话,一定是会进这个判断 zygote = true; // 将zygote设置为true niceName = ZYGOTE_NICE_NAME; // 将niceName设置为zygote_nice_name设置为zygote } else if (strcmp(arg, "--start-system-server") == 0) { // 如果是要启动start-system-server的话 startSystemServer = true; // 会将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) { className.setTo(arg); break; } else { --i; break; } }
然后这几个参数可以怎么去使用呢?
接着看一下后面的代码,是如何使用的。
if (!niceName.isEmpty()) { //如果niceName不为空的话 runtime.setArgv0(niceName.string()); set_process_name(niceName.string()); // 调用这个函数将这个process的name设置为zygote } if (zygote) { // zygote一定为true runtime.start("com.android.internal.os.ZygoteInit", args); //我们进入到了这个判断 } 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; }我们可以看到,runtime是调用了start的方法区进行了这个zygote的启动的工作,那么我们这个runtime是调用的哪边的start呢?
我们在当前的appruntime里面,是没有相关start函数的实现。
那我们去他的父类里面去看一下。
class AppRuntime : public AndroidRuntimeandroidruntime是怎么样的呢?里面有没有start的方法呢?
AndroidRunTime的实现位于:frameworks/base/core/jni/AndroidRuntime.cpp
我们从里面找到了start的方法。
951void AndroidRuntime::start(const char* className, const Vector<String8>& options)952{953 ALOGD(">>>>>> START %s uid %d <<<<<<\n",954 className != NULL ? className : "(unknown)", getuid());955956 static const String8 startSystemServer("start-system-server");957958 /*959 * 'startSystemServer == true' means runtime is obsolete and not run from960 * init.rc anymore, so we print out the boot start event here.961 */962 for (size_t i = 0; i < options.size(); ++i) {963 if (options[i] == startSystemServer) {964 /* track our progress through the boot sequence */965 const int LOG_BOOT_PROGRESS_START = 3000;966 LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));967 }968 }969970 const char* rootDir = getenv("ANDROID_ROOT");971 if (rootDir == NULL) {972 rootDir = "/system";973 if (!hasDir("/system")) {974 LOG_FATAL("No root directory specified, and /android does not exist.");975 return;976 }977 setenv("ANDROID_ROOT", rootDir, 1);978 }979980 //const char* kernelHack = getenv("LD_ASSUME_KERNEL");981 //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);982983 /* start the virtual machine */984 JniInvocation jni_invocation;985 jni_invocation.Init(NULL);986 JNIEnv* env;987 if (startVm(&mJavaVM, &env) != 0) { // 创建虚拟机988 return;989 }990 onVmCreated(env);991992 /*993 * Register android functions.994 */995 if (startReg(env) < 0) { // 注册jni的方法996 ALOGE("Unable to register all android natives\n");997 return;998 }9991000 /*1001 * We want to call main() with a String array with arguments in it.1002 * At present we have two arguments, the class name and an option string.1003 * Create an array to hold them.1004 */1005 jclass stringClass; // class对象1006 jobjectArray strArray; // 对应objectArray对象1007 jstring classNameStr; // 一个string10081009 stringClass = env->FindClass("java/lang/String"); //首先找到了string的class1010 assert(stringClass != NULL);1011 strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); // New 了一个ObjectArray1012 assert(strArray != NULL);1013 classNameStr = env->NewStringUTF(className); // 将className转换为UTF8的类型1014 assert(classNameStr != NULL);1015 env->SetObjectArrayElement(strArray, 0, classNameStr); // 设置objectarray的第一个元素为classname10161017 for (size_t i = 0; i < options.size(); ++i) { // 将后续的参数依次经过转换push到strArray的数组中1018 jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());1019 assert(optionsStr != NULL);1020 env->SetObjectArrayElement(strArray, i + 1, optionsStr);1021 }10221023 /*1024 * Start VM. This thread becomes the main thread of the VM, and will1025 * not return until the VM exits.1026 */1027 char* slashClassName = toSlashClassName(className); // 将className转换为/的形式1028 jclass startClass = env->FindClass(slashClassName); // 寻找这个类1029 if (startClass == NULL) { // 如果找不到的话,我们会返回NULL1030 ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);1031 /* keep going */1032 } else {1033 jmethodID startMeth = env->GetStaticMethodID(startClass, "main",1034 "([Ljava/lang/String;)V"); // 获取我们寻找到的这个类的main函数1035 if (startMeth == NULL) {1036 ALOGE("JavaVM unable to find main() in '%s'\n", className);1037 /* keep going */1038 } else {1039 env->CallStaticVoidMethod(startClass, startMeth, strArray); // 去执行这个类的main函数的方法。10401041#if 01042 if (env->ExceptionCheck())1043 threadExitUncaughtException(env);1044#endif1045 }1046 }1047 free(slashClassName); // free10481049 ALOGD("Shutting down VM\n");1050 if (mJavaVM->DetachCurrentThread() != JNI_OK)1051 ALOGW("Warning: unable to detach main thread\n");1052 if (mJavaVM->DestroyJavaVM() != 0)1053 ALOGW("Warning: VM did not shut down cleanly\n");1054}来根据刚才传递的参数来看一下zygoteInit的main函数
648 public static void main(String argv[]) {649 try {650 // Start profiling the zygote initialization.651 SamplingProfilerIntegration.start();652653 boolean startSystemServer = false;654 String socketName = "zygote";655 String abiList = null;656 for (int i = 1; i < argv.length; i++) {657 if ("start-system-server".equals(argv[i])) {658 startSystemServer = true; // startSystemServer为true659 } else if (argv[i].startsWith(ABI_LIST_ARG)) {660 abiList = argv[i].substring(ABI_LIST_ARG.length());661 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {662 socketName = argv[i].substring(SOCKET_NAME_ARG.length());663 } else {664 throw new RuntimeException("Unknown command line argument: " + argv[i]);665 }666 }667668 if (abiList == null) {669 throw new RuntimeException("No ABI list supplied.");670 }671672 registerZygoteSocket(socketName); // 注册了一个socket,用来与系统中的其他应用程序进行通信673 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,674 SystemClock.uptimeMillis());675 preload(); // 预加载一些资源676 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,677 SystemClock.uptimeMillis());678679 // Finish profiling the zygote initialization.680 SamplingProfilerIntegration.writeZygoteSnapshot();681682 // Do an initial gc to clean up after startup683 gc();684685 // Disable tracing so that forked processes do not inherit stale tracing tags from686 // Zygote.687 Trace.setTracingEnabled(false);688689 if (startSystemServer) { // 如果startSystemServer为true的话,我们会启动systemServer690 startSystemServer(abiList, socketName);691 }692693 Log.i(TAG, "Accepting command socket connections");694 runSelectLoop(abiList); // 进入select的循环,用来响应其他应用程序的请求695696 closeServerSocket();697 } catch (MethodAndArgsCaller caller) {698 caller.run();699 } catch (RuntimeException ex) {700 Log.e(TAG, "Zygote died with exception", ex);701 closeServerSocket();702 throw ex;703 }704 }那么,最后我们对zygote进行一下总结
首先zygote创建了appruntime的对象,并调用他的start。此后的活动由AppRuntime来控制
然后调用startVM来创建了虚拟机,调用startReg来注册JNI的函数
通过JNI调用zygoteInit进入了java的世界
调用registerZygoteSocket来响应子孙后代的请求,同时调用preload函数进行资源的预加载
调用startSystemServer来进行系统启动的后续工作
完成了java世界的初创工作后,变进入了select循环,来处理后续的请求。
- Android启动流程分析(十一) zygote的启动
- Zygote 启动流程分析
- Android zygote启动流程
- Android -- 系统进程Zygote的启动分析
- Zygote进程的启动流程
- android启动过程分析--启动zygote
- android启动过程分析--启动zygote
- Android5 Zygote 与 SystemServer 启动流程分析
- Android runtime机制(二)zygote进程的启动流程
- zygote启动流程
- Zygote进程启动流程
- zygote启动流程
- android 5.0 zygote启动代码流程
- Android系统进程Zygote启动流程
- Android Zygote启动流程源码解析
- Android源码(1) --- Zygote进程启动流程
- android核心机制之Zygote启动流程
- Android Zygote启动流程源码解析
- cxgrid行,列颜色控制
- 观察者模式
- 操作系统之VMware workspace中安装Ubuntu
- 黑马程序员------Java基础学习------多线程
- java DES加密算法
- Android启动流程分析(十一) zygote的启动
- Android新手——DatePicker和TimePicker
- 好记性不如烂笔头76-多线程-通过synchronized实现资源同步
- storm平台搭建(单机版)笔记
- Java使用百度云存储BCS-让你的数据下载飞起来
- Volley自动获取以及存储Cookie
- java PBE算法
- SetBuddyControl动态绑定MapControl
- hadoopshell使用指南