AndroidL系统启动及加载流程分析 下载本文

内容发布更新时间 : 2024/5/20 8:27:07星期一 下面是文章的全部内容请认真阅读。

音乐。

2.4 Zygote启动

Zygote是系统中最重要的服务,在开机过程中zygote进程创建之后系统才进入了java环境,进入了Android环境,另一方面zygote是通过socket接收AMS发送的请求,fork新的应用程序、启动其他的java系统服务。

init进程通过init.${ro.zygote}.rc启动zygote:

AndroidL是64位系统,可以支持两个zygote进程,比以前的版本增加了一个zygote,如果芯片是64位的话,ro.zygote属性为zygote64_32,init则通过init.zygote64_32.rc启动zygote,该rc文件中定义了以下两个zygote服务:

分别通过app_process64,app_process32两个app_process进程来启动zygote、zygote_secondary,其中zygote为primary zygote,进程名为zygote64,会负责创建systemserver进程,一般系统服务进程都是由zygote64进程 fork出来,其他应用进程由另外一个zygote fork。

源码在frameworks/base/cmds/app_process/app_main.cpp。

该服务启动时的主要工作是创建AndroidRuntime、registerZygoteSocket创建socket端口、preload加载类和资源、创建Systemserver进程,下面根据处理的顺序进行逐步解析。

2.4.1 AndroidRuntime创建

AndroidRuntime是android的运行环境(ART),在app_main.cpp中通过

runtime.start(\启动AndroidRuntime。 源码在/frameworks/base/core/jni/AndroidRuntime.cpp AndroidRuntime启动后会创建虚拟机:

Android4.4上还是默认使用Dalvik虚拟机,在开发者选项中兼容ART模式,AndroidL上完全采用了ART,加载libart.so。

startVm( )函数,首先会完成虚拟机很多资源的分配,然后初始化ART相关的option、调用JNI_CreateJavaVM()创建ART虚拟机。

由于Dalvik VM的效率不高,在android4.4开始,google就开发了AndroidRuntime即android运行环境。Dalvik虚拟机下,应用每次运行都要将字节码转成机器码,ART不同,应用第一次安装的时候,通过dex2oat字节码就会转成机器码,并保存起来,理论上应用启动时会更快。(但是之前陈翔工针对ART和Dalvik作过对比测试,从对比数据上看,ART下应用的启动速度提高没有很明显,而且由于安装时的dex2oat过程,导致应用的安装和系统的启动速度会较慢,可能后期的版本androidL有优化。)

2.4.2 registerZygoteSocket

AndroidRuntime启动完虚拟机之后,会创建的第一个虚拟机java进程就是ZygoteInit进程,这个ZygoteInit进程可以理解成真正的zygote,在zygoteInit的main函数中首先就是调用registerZygoteSocket(“zygote”), 注册一个LocalServerSocket类型的Socket通道,变量命名为sServerSocket,作为Socket的服务端。当SystemServer进程创建后,在SystemServer进程中则会创建一个Socket客户端LocalSocket,具体实现在Process.java中。 这样就创建了一个zygote和SystemServer进程的socket通信通道,所谓zygote是应用孵化器,就是利用该Socket 创建其他的应用进程。

当服务端LocalServerSocket端口准备好后,ZygoteInit的main()函数调用runSelectLoop ()进入非阻塞读操作循环,通过selectReadable()将文件描述符添加到select的列表中,如果有请求就调用ZygoteConnection类的runOnce()函数处理每一个Socket接收到的命令。

当要创建新应用时,客户端SystemServer进程中 ActivityManagerService通过startActivity()一步步调用到的StartProcessLocked()函数进入Process.java,最终通过startViaZygote ->zygoteSendArgsAndGetPid,通过LocalSocket发给zygote进程,zygote在通过runOnce函数fork新进程。

2.4.3 preload预加载类和资源

创建完socket之后,zygote进程开始调用preload()函数加载类和资源等信息。

这个过程会预装的Framework大部分类及资源。preloadClasses()加载的类列表是在framework.jar中的一个文本文件列表,名称为preload-classes,该列表的原始定义在frameworks/base/preload-classes文本文件中,该文件是通过

frameworks/base/tools/preload/WritePreloadedClassFile.java类自动生成的。在Android源码编译的时候,会最终把preload-classes文件打包到framework.jar中。

预加载的资源是在frameworks/base/core/res/res/values/arrays.xml中被定义的,包含两类资源,一类是drawable资源,另一类是color资源,preloadResources()通过分别调用preloadDrawables()和preloadColorStateLists()加载这两类资源。

preloadSharedLibraries()函数加载链接库。

2.4.4 SystemServer进程创建

Zygote进程加载完类和资源后,如果需要创建SystemServer(zygote64)则通过startSystemServer()->Zygote.forkSystemServer创建SystemServer进程,SystemServer进程几乎是所有java系统服务的守护进程。

SystemServer启动后首先加载libandroid_servers.so并调用nativeInit()进行初始化,之后就要启动Android的java系统服务Power Manager、Activity Manager、PackageManager、

WindowManager等服务,在AndroidL之前的版本在这里将会创建一个ServerThread线程,由ServerThread线程启动这些Android Java 的关键服务。而AndroidL上没有ServerThread线程,而是创建了一个SystemServiceManager服务来启动管理这些系统服务,并且将系统服务区分为Bootstrap服务、Core服务、Other服务,分别启动这些服务:

Installer、ActivityMangerService、PowerManagerService、DisplayManagerSerivce和PackageManagerServcie作为Bootstrap服务启动,LightsService、BatteryService、

UsageStatsService、WebViewUpdateService服务作为第二阶段在startCoreServices()函数执行,其余的服务的启动和systemReady的处理在startOtherServices()中。

在系统启动过程中,有些服务需要等待其他条件或者其他服务初始化完成之后再启动,AndroidL中的处理跟之前的版本也有不同,之前的版本上是直接调用waitForxxx() 函数等待响应的服务处理,而L上将系统的启动分为几个阶段:

通过调用SystemServiceManager类中的startBootPhase(final int phase) 设置启动阶段: