全方位认识zygote启动过程

时间:2022-01-14 04:32:08

在init.rc中有如下一段:

 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
     class main
     socket zygote stream 660 root system
     onrestart write /sys/android_power/request_state wake
     onrestart write /sys/power/state on
     onrestart restart media
     onrestart restart netd

(关于init进程我会重新写一遍文章介绍,这里只讲zygote的启动)

zygote的实际进程是/system/bin/app_process,通过提供适当的参数即可给你的java程序提供一个虚拟机环境以供运行。

这里我们先来看看另外一个使用app_process 的地方,这就是当你运行adb install 的时候,惊呆了吧?

看frameworks\base\cmds\pm\pm文件的内容便知,

base=/system
export CLASSPATH=$base/framework/pm.jar
exec app_process $base/bin com.android.commands.pm.Pm "$@"

该shell脚本实现了从c或者shell环境调用java的目的,很神奇吧?还有我们熟悉的adb shell am start -a "ACTION"中的am也是采用相同原理实现的。


那我们就来看看app_process是个神马东东。

入口在frameworks\base\cmds\app_process\app_main.cpp中的main函数。先来看个图

全方位认识zygote启动过程

详细的代码流程就不介绍了,自个看代码去吧,再说就算你看了代码如果不从整体上来了解最终也是事倍工半的。

app_process中定义了一个类 class AppRuntime : public AndroidRuntime

显然继承自AndroidRuntime并实现了其中的几个接口,onStarted、onZygoteInit、onExit。记住这个内部类很重要,他是一切的开始和承接点!

上图显示的是init.rc中启动systemserver的过程,此外还有pm命令,应用程序的启动都是从此开始,服务先启动,然后再是应用。

1.systemserver的启动

通过init.rc中向app_process传入参数调用,app_process调用AppRuntime的start函数,即AndroidRuntime的start函数,它初始化了javavm,注册

了系统服务等需要用到的JNI方法,这是运行java程序的基础,然后调用ZygoteInit的main函数,在其中预加载类和资源,注册zygote socket,一方面

等待AMS的连接以创建应用进程,一方面运行startSystemServer产生systemserver 进程,并调用RuntimeInit的zygoteInit方法,后者调用nativeZygoteInit

方法,该方法是jni方法,实现在AndroidRuntime中,jni方法调用gCurRuntime->onZygoteInit(),gCurRuntime就是AppRuntime了,该方法用来开始binder

通信,然后通过applicationInit调用到了SystemServer的main方法,于是systemserver就启动了。

2.pm的启动

在app_process中有这么一段

    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "");
    } else if (className) {
        // Remainder of args get passed to startup class main()
        runtime.mClassName = className;
        runtime.mArgC = argc - i;
        runtime.mArgV = argv + i;
        runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool");
    }

pm是通过       

runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool");

来启动的,即相对SystemServer运行的是RuntimeInit中的main方法,然后调用jni方法nativeFinishInit,同样是实现在AndroidRuntime中,通过调用AppRuntime的onStarted方法来调用命令行参数class com.android.commands.pm.Pm 的main方法。


从上可知,systemserver启动调用流程是app_process->AndroidRuntime->ZygoteInit->RuntimeInit

                  pm的流程是app_process->AndroidRuntime->RuntimeInit,当然也得益于systemserver先运行来预加载类等在ZygoteInit中的操作。