Zygote的启动过程解析。
Zygote实际上是一个用户态应用程序,由启动脚本负责启动。在启动脚本中Zygote叫做app_process。下面分析app_main.cpp中的启动Zygote的过程。
main
|__设置runtime的mParentDir为/usr/bin,mArgC为zygote参数个数,mArgV为zygote参数(-Xzygote /system/bin --zygote --start-system-server)
|__runtime.start(AndroidRuntime::start)
|__设置环境变量ANDROID_ROOT
|__startVm():启动VM
|__设置启动虚拟机参数,如:checkjni,进程堆大小16MB等
|__调用JNI_CreateJavaVM()启动虚拟机,之后JavaVM和虚拟机主线程的JNIEnv变量有效
|__startReg():向虚拟机主线程注册JNI
|__com.android.internal.os.ZygoteInit.main(从JNI调用,从此进入JAVA世界)
|__registerZygoteSocket():创建Zygote服务端本地socket,用于监听客户端的连接请求
|__preloadClasses():预先加载preloaded-classes文件中指定的类(此过程耗时较大,好处是加快后续应用程序的启动)
|__preloadResources():预先加载资源
|__gc():手动执行一次垃圾回收
|__startSystemServer():启动一个子进程来运行system_server
|__硬编码启动system_server时使用的参数
|__调用Zygote.forkSystemServer()创建子进程
|__调用forkAndSpecializeCommon()创建子进程(调用fork()创建子进程且设置子进程相关uid、gid等属性)
|__对于创建子进程失败则直接将Zygote进程杀死(Zygote进程与system_server进程生死与共)
|__返回子进程ID
|__在子进程中调用handleSystemServerProcess()运行system_server
|__关闭父进程Zygote打开的本地服务端socket
|__执行RuntimeInit.zygoteInit()运行system_server
|__调用AppRuntime::onZygoteInit()。实际上是与binder建立联系
|__调用invokeStaticMain()执行systemserver类的main函数
|__调用Class.forName()根据类名反射出类对象
|__调用类的getMethod()方法获取systemserver类的main方法
|__调用ZygoteInit.MethodAndArgsCaller()抛出一个异常且该异常中包含systemserver类的main方法
|__runSelectLoopMode():使用多路复用I/O机制监听连接到Zygote本地服务器的socket且执行响应处理
|__进入死循环监听Zygote本地服务端socket,当有客户端连接Zygote本地服务端socket后,调用ZygoteConnection.runOnce()执行该服务请求
|__ZygoteConnection.runOnce()
|__调用Zygote.forkAndSpecialize()函数创建一个子进程
|__在子进程中执行handleChildProc()处理客户端请求
|__关闭父进程Zygote创建的服务端socket
|__执行RuntimeInit.zygoteInit()运行客户端请求
|__调用AppRuntime::onZygoteInit()。实际上是与binder建立联系
|__调用invokeStaticMain()执行客户端请求类的main函数
|__调用Class.forName()根据类名反射出类对象
|__调用类的getMethod()方法获取客户端请求类的main方法
|__调用ZygoteInit.MethodAndArgsCaller()抛出一个异常且该异常中包含客户端请求类的main方法
|__MethodAndArgsCaller.run():在异常处理函数处,用于启动连接到Zygote服务器端socket的客户端程序以及system_server主函数。(Zygote处理连接端数据时在最后使用抛异常的机制运行客户端主函数)。
可以得出一个结论:system_server的启动过程和其他应用进程的启动过程是一致的,他们都是Zygote的子进程。
SystemServer启动解析
main
|__System.loadLibrary(“android_servers”)加载JNI库
|__init1()执行init1(JNI函数)
|__执行system_init()
|__设置参数准备将system_server加入binder
|__调用执行Java代码的init2函数
|__创建一个线程执行android.server.ServerThread
|__启动各种服务,如:电源管理、电池管理、蓝牙等
|__等待新的服务请求。
|__最终将system_server添加到binder中
当有新的服务请求到后,system_server会调用服务请求的处理函数做如下事情:
1)与Zygote本地服务端Socket建立连接;
2)将待执行的类名组成指定的格式发送给Zygote;
3)Zygote接收到客户端的请求后,调用ZygoteConnection.runOnce()执行该服务请求,即:创建一个子进程来运行指定类对象的main函数。