驰易网站建设,淘宝关键词排名,wordpress展示备案号,免费的服务器有哪些在上一篇init进程启动流程中已经提到#xff0c;在init中会解析一个init.rc文件#xff0c;解析后会执行其中的命令来启动zygote进程、serviceManager进程等#xff0c;下面我们来看一下#xff1a;
//文件路径#xff1a;system/core/init/init.cppstatic void LoadBoot…在上一篇init进程启动流程中已经提到在init中会解析一个init.rc文件解析后会执行其中的命令来启动zygote进程、serviceManager进程等下面我们来看一下
//文件路径system/core/init/init.cppstatic void LoadBootScripts(ActionManager action_manager, ServiceList service_list) {//创建解析器Parser parser CreateParser(action_manager, service_list);std::string bootscript GetProperty(ro.boot.init_rc, );if (bootscript.empty()) {//解析init.rc ,这个是手机设备上的路径和源码中system/core/rootdir/init.rc是一个文件parser.ParseConfig(/system/etc/init/hw/init.rc);if (!parser.ParseConfig(/system/etc/init)) {late_import_paths.emplace_back(/system/etc/init);}// late_import is available only in Q and earlier release. As we dont// have system_ext in those versions, skip late_import for system_ext.parser.ParseConfig(/system_ext/etc/init);if (!parser.ParseConfig(/product/etc/init)) {late_import_paths.emplace_back(/product/etc/init);}if (!parser.ParseConfig(/odm/etc/init)) {late_import_paths.emplace_back(/odm/etc/init);}if (!parser.ParseConfig(/vendor/etc/init)) {late_import_paths.emplace_back(/vendor/etc/init);}} else {parser.ParseConfig(bootscript);}
}
我们来看一下这个init.rc中和zygote相关的部分
#文件路径system/core/rootdir/init.rc 或设备上 /system/etc/init/hw/init.rc#引入子rc文件${ro.zygote}是一个变量取值范围zygote32、zygote64、zygote32_64、zygote64_32会根据实际设备是32位还是64位进行选择
import /system/etc/init/hw/init.${ro.zygote}.rc# Mount filesystems and start core system services.
on late-init# Now we can start zygote for devices with file based encryption#在init启动后的一个时机触发启动zygote进程trigger zygote-starton zygote-start property:ro.crypto.stateunencrypted# A/B update verifier that marks a successful boot.exec_start update_verifier_nonencryptedstart statsdstart netdstart zygote #启动zygote进程那么这个zygote是什么呢start zygote_secondary#还记得文件开头处的import 引入的子rc文件吗我们以init.zygote64.rc为例
#文件路径 system/core/rootdir/init.zygote64.rc#service zygote 服务名为zygote
#对应的可执行程序路径/system/bin/app_process64 设备上的路径
#-Xzygote /system/bin --zygote --start-system-server 执行app_process64时传入的参数
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-serverclass mainpriority -20user root #用户角色group root readproc reserved_disksocket zygote stream 660 root systemsocket usap_pool_primary stream 660 root system#如果意外挂掉需要重启的服务onrestart exec_background - system system -- /system/bin/vdc volume abort_fuseonrestart write /sys/power/state ononrestart restart audioserveronrestart restart cameraserveronrestart restart mediaonrestart restart netdonrestart restart wificondwritepid /dev/cpuset/foreground/tasks和上一篇中的init一样zygote进程也具化到了设备中的执行程序即app_process我们来看下他是由那个文件编译出来的。
//文件路径 frameworks/base/cmds/app_process/Android.bpcc_binary {name: app_process,srcs: [app_main.cpp], //是同目录的app_main.cpp...
}
至于怎么去找这么文件的路径目前没有发现太好的办法只能是多熟悉每一层的bp编译脚本关键字搜索。
打开app_main.cpp文件
//文件路径framesworks/base/cmds/app_process/app_main.cpp//argv :-Xzygote /system/bin --zygote --start-system-server
int main(int argc, char* const argv[])
{//创建了android运行时环境AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));//根据传入的参数设置变量值bool zygote false;bool startSystemServer false;bool application false;String8 niceName;String8 className;while (i argc) {const char* arg argv[i];if (strcmp(arg, --zygote) 0) { //传入参数中有--zygote所以zygote truezygote true;niceName ZYGOTE_NICE_NAME;} else if (strcmp(arg, --start-system-server) 0) { //同理startSystemServer truestartSystemServer 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;}}VectorString8 args;if (!className.isEmpty()) {...}else {// Were in zygote mode.maybeCreateDalvikCache();if (startSystemServer) { //上面已经赋值为true// args中又添加了这个参数args.add(String8(start-system-server));}...// In zygote mode, pass all remaining arguments to the zygote// main() method.for (; i argc; i) {args.add(String8(argv[i]));}}...if (zygote) {//启动运行时环境,这里就是有native转到到java层的入口这也是为什么说zygote是java层进程的鼻祖runtime.start(com.android.internal.os.ZygoteInit, args, zygote);} else if (className) { //而这个分支是启动app相关的流程可以先有个印象后续分析到应用的启动流程可能还会看到这里// 将上面的args参数数组传入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.);}
}
继续跟踪runtime.start()方法runtime是AppRuntime类型但AppRuntime并没有start(),因为是定义在AppRuntime的父类中找到此方法看下具体操作
//文件路径 frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const VectorString8 options, bool zygote)
{bool primary_zygote false;/** startSystemServer true means runtime is obsolete and not run from* init.rc anymore, so we print out the boot start event here.*///根据options参数判断是否是第一次启动zygotefor (size_t i 0; i options.size(); i) {if (options[i] startSystemServer) {primary_zygote true;/* 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)));}}//设置android root目录环境变量const char* rootDir getenv(ANDROID_ROOT);if (rootDir NULL) {rootDir /system;if (!hasDir(/system)) {LOG_FATAL(No root directory specified, and /system does not exist.);return;}setenv(ANDROID_ROOT, rootDir, 1);}JNIEnv* env;if (startVm(mJavaVM, env, zygote, primary_zygote) ! 0) { //启动虚拟机设置虚拟机的参数默认值return;}if (startReg(env) 0) { //注册JNI方法系统api中涉及的jni方法都是在这里注册的ALOGE(Unable to register all android natives\n);return;}char* slashClassName toSlashClassName(className ! NULL ? className : );jclass startClass env-FindClass(slashClassName);if (startClass NULL) {}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 {//jni 执行ZygoteInit.java 的main()方法由此过渡到java层env-CallStaticVoidMethod(startClass, startMeth, strArray);}}
}
这里放一张图用于表示进程与虚拟机的关系即每个进程都有独立的虚拟机而虚拟机就是一块大的内存区域这块大内存又划分为堆、线程栈、方法区、程序计数器、本地方法栈等等更小的内存块。 继续上面的流程进入java层的com.android.internal.os.ZygoteInit的main()函数
// 文件路径frameworks\base\core\java\com\android\internal\os\ZygoteInit.javapublic static void main(String argv[]) {ZygoteServer zygoteServer null;//根据传入的参数设置变量for (int i 1; i argv.length; i) {if (start-system-server.equals(argv[i])) { //由层传入所以startSystemServer truestartSystemServer true;} else if (--enable-lazy-preload.equals(argv[i])) {enableLazyPreload 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)) {zygoteSocketName argv[i].substring(SOCKET_NAME_ARG.length());} else {throw new RuntimeException(Unknown command line argument: argv[i]);}}if (!enableLazyPreload) {bootTimingsTraceLog.traceBegin(ZygotePreload);EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,SystemClock.uptimeMillis());//预加载系统资源文件应用进程都是zygote进程fork出来的在此进行预加载就不用在应用进程中再去重复加载资源文件提升应用启动速度preload(bootTimingsTraceLog);EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis());bootTimingsTraceLog.traceEnd(); // ZygotePreload}...zygoteServer new ZygoteServer(isPrimaryZygote);if (startSystemServer) {//启动SystemServer进程,有zygote fork而来Runnable r forkSystemServer(abiList, zygoteSocketName, zygoteServer);// {code r null} in the parent (zygote) process, and {code r ! null} in the// child (system_server) process.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.//死循环等待Ams发出的创建应用进程的消息caller zygoteServer.runSelectLoop(abiList);
}zygote进程重要事项总结
c层
创建Android runtime启动虚拟机注册JNI方法通过JNI调用ZygoteInit.java的main(),转入到java层
java层
预加载一些系统资源如一些java类resources文件Graphics驱动、hal层的资源、动态库相关的操作等等创建zygoteServer 服务端socket等待AMS发出的创建应用进程的消息。fork 出systemServer进程