在之前的文章中我们已经分析到Zygote
最后在Linux
的init
进程中是通过如下代码启动Java
层的ZygoteInit
。
|
|
所以我们进入runtime.start()
方法看下它的具体实现。
AndroidRuntime
frameworks/base/core/jni/AndroidRuntime.cpp
|
|
根据上面的代码注释,小憩将start()
方法分为四步:
- 创建虚拟机
- 通过
JNI
注册Android Native
方法 - 拼接参数、获取
ZygoteInit Class
与其对应的main
方法id
- 调用
ZygoteInit.main()
方法,进去Java
层
创建虚拟机
通过startVm()
来创建虚拟机。
|
|
该方法很长,但主要任务就是设置虚拟机的相关参数,具体各个属性的作用就不做分析,感兴趣的可以自行google
对应搜索。
JNI方法注册
通过startReg()
来注册Android Native
方法。
|
|
主要部分是通过register_jni_procs
来注册JNI
方法。对应的是gRegJNI
|
|
方法很多就不一一列举出来。
举个例子,例如:
|
|
对应的就是com/android/internal/os/ZygoteInit
中的nativeZygoteInit()
方法,而nativeZygoteInit()
方法通过JNI
注册之后,在Linux
的具体实现是对应的com_android_internal_os_ZygoteInit_nativeZygoteInit()
方法。
|
|
最后它会调用onZygoteInit()
方法,它的具体实现在app_main.cpp
中
|
|
参数、类、方法构建与调用
在这一步主要通过FindClass()
方法来获取对应Java
的Class
类型,构建对应的String[]
类型的参数与ZygoteInit Class
。
再通过GetStaticMethodID()
方法来获取对应main()
方法的方法id
,以便为之后调用ZygoteInit.main()
方法做准备。
最后在通过CallStaticVoidMethod()
来调用ZygoteInit.main()
方法,最终进入Java
层的ZygoteInit
。
从runtime.start()
到调用Java
层的ZygoteInit.main()
的整个过程流程图如下:
ZygoteInit
|
|
终于见到Java
代码了,不容易啊~
首先会创建zygoteServer
,为Zygote
设置自己的进程分组id
;然后会解析传递过来的参数,根据参数执行之后的后续操作。
注册Socket
|
|
通过registerServerSocketFromEnv
来注册socket
,使用LocalServerSocket
创建本地socket
服务,来监听对于的文件描述符fd
。
预加载
|
|
对于类加载,采用反射机制Class.forName()
方法来加载。
对于资源加载,主要是com.android.internal.R.array.preloaded_drawables
和com.android.internal.R.array.preloaded_color_state_lists
,在应用程序中以com.android.internal.R.xxx
开头的资源,便是此时由Zygote
加载到内存的。
在这里预加载目的是为了之后fork
出子的进程,同时使用copy on write
技术,使得子进程在只读模式下与父进程共用一块内存空间,从而保证子进程能够迅速fork
处理,减少数据的拷贝数量。
SystemServer
|
|
创建system_server
服务,具体实现后续到system_server
的时候再分析。
runSelectLoop
|
|
Zygote
采用高效的I/O
多路复用机制,保证在没有客户端连接请求或数据处理时休眠,否则响应客户端的请求。
processOneCommand
|
|
通过fork
方法来创建子进程,该方法会返回两次结果;如果为0
则代表当前需要执行子进程的相关逻辑,非0
则是父进程的逻辑。
至此Zygote
的启动就完成了。
所以在Java
层Zygote
主要做的事情为:
- 通过
registerServerSocketFromEnv
来注册socket
- 通过
preload
预加载类、drawable
与color
资源、openGL
、共享库与WebView
相关资源 - 创建
system_server
服务 runSelectLoop
等待新消息的到来,并创建新进程
Zygote
中的一个重要步骤:启动system_server
后续再进行分析,敬请期待!
项目
android_startup: 提供一种在应用启动时能够更加简单、高效的方式来初始化组件。开发人员可以使用android-startup
来简化启动序列,并显式地设置初始化顺序与组件之间的依赖关系。 与此同时android-startup
支持同步与异步等待,并通过有向无环图拓扑排序的方式来保证内部依赖组件的初始化顺序。
AwesomeGithub: 基于Github
客户端,纯练习项目,支持组件化开发,支持账户密码与认证登陆。使用Kotlin
语言进行开发,项目架构是基于Jetpack&DataBinding
的MVVM
;项目中使用了Arouter
、Retrofit
、Coroutine
、Glide
、Dagger
与Hilt
等流行开源技术。
flutter_github: 基于Flutter
的跨平台版本Github
客户端,与AwesomeGithub
相对应。
android-api-analysis: 结合详细的Demo
来全面解析Android
相关的知识点, 帮助读者能够更快的掌握与理解所阐述的要点。
daily_algorithm: 每日一算法,由浅入深,欢迎加入一起共勉。