• Android Framework基础知识:Zygote启动流程


    一、前言

            准备工作

            模拟器版本:MuMu模拟器(Android 6.0版本)  (为什么用它?因为不用自己Root,又可以不用自己手机😀)

            源码查看地址:10.0.0_r6 - Android社区 - https://www.androidos.net.cn/ (一些内核源码就可以到这里查看)

            简单概括下Framework知识:

    • Zygote:负责创建App进程
    • ActivityManagerService(AMS):负责四大组件(Activity、Service等)的启动。
    • PackageManagerService(PMS):负责给AMS提供需要的四大组件信息。

    本章主要讲解Zygote的如何启动和启动后一些相关任务。

    接下来,我们先看下Zygote是如何启动流程。

    温馨提示:本节大部分都是一些源码流程,能梳理清流程即可。

    二、Zygote如何启动

            说到Zygote是如何启动的,那么就需要从Android开机说起。

    Andorid开机时,会去先执行init文件,如上图文件。

    温馨提示:上面的init等文件,需要手机root后才能查看,没有root条件可以下一个MuMu模拟器。

    2.1 init文件

            功能:init文件由下面文件编译成可执行文件init,相当于.exe可执行程序,然后会在文件执行后,去启动init.rc脚本

            路径:init - Android社区 - https://www.androidos.net.cn/

    2.2 init.rc

             功能:存放一堆任务清单,导入了zygote脚本。

     代码如下:

    2.3 zygote32.rc 

            功能:启动 app_process,并改名为zygote

    启动代码:

    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

    app_main.cpp - Android社区 - https://www.androidos.net.cn/

    • /system/bin/app_process:程序位置,对应的代码如下
    •  到此,Zygote的启动就到此为止了。

    简单点概括就是:手机开机就启动Zygote,开个玩笑。

    正确的流程方式:手机开机后会先去执行init文件,启动init.rc脚本,在脚本里启动了Zygote。

    既然启动了Zygote,那么就继续往app_main.cpp文件里走。

    三、Zygote启动流程

            接下来来到app_main.cpp文件,直接看main程序执行代码:

    3.1 app_main main代码

    可以看到,main代码里对我们在 zygote32.rc 文件中启动 Zygote 所传入的参数进行判断。

    并且zygote = true。

    c1240c4be2d85761d30774f28a359d4d.png

    代码的最后,由于zygote==true,启动了ZygoteInit Java程序(注意:这个Java程序还是一个Native 进程)

    并且把 zygote32.rc 所传入的参数又传给了ZygoteInit

     

    3.2 ZygoteInit代码

    在ZygoteInit的main方法中,有如下代码:

    main方法里,主要梳理了两个流程。

    • 预加载各种资源(例如:android.view,android.widget和一些java.io,java.lang等)
    • 启动各种服务(AMS,PMS等)

    接下来走一边预加载各种资源流程

    3.2.1 预加载各种资源

    我们知道,enableLazyPreload肯定是false,因为启动Zygote的命令里没有"--enable-lazy-preload"

    就会来到下面代码,执行preLoad方法,接着往里面看

    在这个方法里,会预加载很多资源,我们先从preloadClasses方法入手

    通过方法的注释,我们可以知道,用来加载和初始化一些常用的类。我们看看PRELOADED_CLASSES 到底是什么

    PRELOADED_CLASSES 如下:顺着下面路径往系统目录找

    这就很清晰了,不都是一些我们经常用到的类嘛。包括(android.view,android.widget和一些java.io,java.lang等),接着往下看

    接着就会把上面的文件,一行一行的读取,通过Class.forName加载进内存。代码如下:(注意:只会加载一份)

    最后,还会去加载preloadResources(加载系统资源,也就是我们经常引用的系统样式等),preloadSharedLibraries(加载so库),preloadTextResources(字体资源),还有一些其他的预加载,可以自行看代码。

     再次会到ZygoteInit的main方法中,继续往下走 启动服务流程

    3.2.2 启动服务流程

    创建一个SystemServer与Zygote通信,通过Socket

    通过Zygote创建SystemServer进程(Java进程)

    执行SystemServer的main,执行run方法

    启动服务,其中startBootstrapServices就启动了我们的AMS,PMS

    创建PMS

    创建AMS

     

    到此,Zygote的介绍到此结束。留几个问题给各位思考一下:

    • 问题1:Zygote为什么用Socket不用Binder?
    • 问题2:每个App都会将系统的资源,系统的类都加载一遍吗?
    • 问题3:init程序和init.rc的关系
    • 问题3:AMS能直接调用PMS嘛?

  • 相关阅读:
    webrtc推拉流 srs报错:DTLS_HANG DTLS: > Hang, done=0, version=-1, arq=0
    VB.net进行CAD二次开发(四)
    Hertz 性能持续优化,如何准确进行 Hertz 压测?这里有一份性能测试指南
    CMake使用基础汇总
    新品发布 | Cloudpods 3.9.2 版本上线!
    VScode 右键没有转到定义等的菜单
    Spring全家桶 源码 入门系列(一) --------容器与 bean
    Python安装和环境配置教程
    锁升级过程(无锁、偏向锁、轻量级锁、重量级锁)
    『现学现忘』Git基础 — 15、blob对象详解
  • 原文地址:https://blog.csdn.net/wumeixinjiazu/article/details/126014751