Android10 系统进程Zygote启动

1、Android10 源码编译相关问题

2、Android10 系统进程Zygote启动

3、Android10 系统进程SystemServer

4、Android10 launcher启动流程

5、Android10 系统发送开机广播时机

6、Android10 AppComponentFactory源码梳理

7、Android10 InputManagerService事件输入输出

8、Android10 InputManagerService本地实现

9、Android10 SystemUI系统手势导航


        zygote进程可以理解为Android系统的根进程,有了Zygote进程后,在Zygote进程中会创建SystemServer进程,在SystemServer进程中会去初始化Android系统所需的各种系统服务,先看下整体流程:

        电源键按下——>bootloader——>kernal——>init——>zygote——>SystemServer

bootloader:类似于电脑的BIOS引导程序

kernal:android内核层,主要是加载硬件驱动程序,最后会创建一个init进程(/kernal/init/main.c——>kernal_init()——>run_init_process())

init:init进程,linux下的第一个进程,最后会去创建一个Zygote进程(/system/core/rootdir/init.rc——>/system/core/rootdir/init.zygote*.rc——>/framework/base/cmds/app_process/app_main.cpp)

zygote:zygote进程可以理解为android系统的根进程,在init进程执行app_main.cpp这个类的main函数是,会先去创建虚拟机,然后会调用到framework层的com.android.internal.os.ZygoteInit的main函数去初始化一些逻辑

SystemServer:Zygote作为android系统的根进程,首先会去创建一个SystemServer进程,在SystemServer进程中会去初始化各种android系统所需的服务

zygote进程java层初始化

        zygote进程在/frameworks/base/cmds/app_process/app_main.cpp开始初始化,会先去创建虚拟机,最后通过ZygoteInit进入到java世界,我们就先从ZygoteInit(/frameworks/base/core/java/com/android/internal/os/ZygoteInit)的Main函数开始进入:

public static void main(String argv[]) {
     // 1.创建ZygoteServer
     ZygoteServer zygoteServer = null;
     // 调用native函数,确保当前没有其它线程在运行
     ZygoteHooks.startZygoteNoThreadCreation();
     //设置pid为0,Zygote进入自己的进程组
     Os.setpgid(0, 0);
     ......
     Runnable caller;
     try {
         ......
         //得到systrace的监控TAG
         String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
         TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,Trace.TRACE_TAG_DALVIK);
         //通过systradce来追踪 函数ZygoteInit, 可以通过systrace工具来进行分析
         //traceBegin 和 traceEnd 要成对出现,而且需要使用同一个tag
         bootTimingsTraceLog.traceBegin("ZygoteInit");
         //开启DDMS(Dalvik Debug Monitor Service)功能
         //注册所有已知的Java VM的处理块的监听器。线程监听、内存监听、native 堆内存监听、debug模式监听等等
         RuntimeInit.enableDdms();
         boolean startSystemServer = false;
         String zygoteSocketName = "zygote";
         String abiList = null;
         boolean enableLazyPreload = false;
 
         //2. 解析app_main.cpp - start()传入的参数
         for (int i = 1; i < argv.length; i++) {
             if ("start-system-server".equals(argv[i])) {
                 startSystemServer = true; //启动zygote时,才会传入参数:start-system-server
             } else if ("--enable-lazy-preload".equals(argv[i])) {
                 enableLazyPreload = true; //启动zygote_secondary时,才会传入参数:enable-lazy-preload
             } else if (argv[i].startsWith(ABI_LIST_ARG)) { //通过属性ro.product.cpu.abilist64\ro.product.cpu.abilist32 从C空间传来的值
                 abiList = argv[i].substring(ABI_LIST_ARG.length());
             } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                 zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length()); //会有两种值:zygote和zygote_secondary
             } else {
                 throw new RuntimeException("Unknown command line argument: " + argv[i]);
             }
         }

         // 根据传入socket name来决定是创建socket还是zygote_secondary
         final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
         // 在第一次zygote启动时,enableLazyPreload为false,执行preload
         if (!enableLazyPreload) {
             //systrace 追踪 ZygotePreload
             bootTimingsTraceLog.traceBegin("ZygotePreload");
             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
             SystemClock.uptimeMillis());

             // 3.加载进程的资源和类
             preload(bootTimingsTraceLog);
             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
             SystemClock.uptimeMillis());
             //systrae结束 ZygotePreload的追踪
             bootTimingsTraceLog.traceEnd(); // ZygotePreload
          } else {
                 // 延迟预加载, 变更Zygote进程优先级为NORMAL级别,第一次fork时才会preload
             Zygote.resetNicePriority();
          }

         //结束ZygoteInit的systrace追踪
         bootTimingsTraceLog.traceEnd(); // ZygoteInit
         //禁用systrace追踪,以便fork的进程不会从zygote继承过时的跟踪标记
         Trace.setTracingEnabled(false, 0);
         // 4.调用ZygoteServer 构造函数,创建socket,会根据传入的参数,
         // 创建两个socket:/dev/socket/zygote 和 /dev/socket/zygote_secondary
         zygoteServer = new ZygoteServer(isPrimaryZygote);
         if (startSystemServer) {
             //5. fork出system server
             Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
             // 启动SystemServer
             if (r != null) {
                 r.run();
                 return;
             }
         }

         // 6. zygote进程进入无限循环,处理请求,在ActivityMangerService中请求创建进程时就会执行到这里,比如打开一个新的应用
         caller = zygoteServer.runSelectLoop(abiList);
     } catch (Throwable ex) {
         Log.e(TAG, "System zygote died with exception", ex);
         throw ex;
     } finally {
         if (zygoteServer != null) {
             zygoteServer.closeServerSocket();
         }
     }

     // 7.在子进程中已经退出了select循环。继续执行命令
     if (caller != null) {
           caller.run();
     }
 }

对于代码中标序号的,这里说明几点:

第3点预加载

什么是预加载:

预加载是指在zygote进程启动的时候就加载,这样系统只在zygote执行一次加载操作,所有APP用到该资源不需要再重新加载,减少资源加载时间,加快了应用启动速度,一般情况下,系统中App共享的资源会被列为预加载资源。

zygote fork子进程时,根据fork的copy-on-write机制可知,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。

预加载的原理:

zygote进程启动后将资源读取出来,保存到Resources一个全局静态变量中,下次读取系统资源的时候优先从静态变量中查找。

第4点创建Socket

        通过ZygoteServer创建Socket是通过文件描述符来创建的,内部会保存描述符用于后续Socket的创建,主要作用是:1、用于创建SystemServer;2、通过调用ZygoteServer.runSelectLoop()用于等待后续请求进程的创建。

第5点SystemServer创建

        在forkSystemServer()方法中,会去执行handleSystemServerProcess()方法,最终会创建SystemServer进程,并执行SystemServer的main()方法,由此就进入到SystemServer并初始化各种系统服务

第6点执行runSelectLoop

        这是一个无限循环函数,里面开启了一个Socket来监听请求,它有什么作用呢?我们这里直接举一个列子:

        假如有一个没有启动的A应用,现在我们点击A应用的启动图标,这个时候就会进入到ActivityManagerService中去检查A应用是否启动了,没有启动的话,就会通过Socket请求创建A应用的进程,最终就会执行到runSelectLoop这个函数中去创建进程,最终会执行到android.app.ActivityThread的main()函数,这也就是为什么我们有时会听到,一个应用进程是从ActivityThread开始的。

好了,Zygote进程就到这里,下一篇再来看看SystemServer进程。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值