Android Framework实战视频--Zygote的启动

Android 8.1 zygote 启动过程源码

课程答疑和新课信息:QQ交流群:422901085进行课程讨论
FrameWork入门课视频链接:https://edu.youkuaiyun.com/course/detail/30298
FrameWork实战课1视频链接:https://edu.youkuaiyun.com/course/detail/30275
专题博客系列:
Android 8.1 zygote 启动过程源码
Android Framework实战视频–Zygote的fork进程篇
Android Framework实战视频–SystemServer启动篇
Android Framework实战视频–SystemServer启动FallbackHome篇
Android Framework实战视频–FallbackHome进程启动及Activity启动篇
Android Framework实战视频–FallbackHome结束启动Launcher篇

1、Zygote 简单介绍

在Android系统中,普通应用程序进程以及运行系统的服务system_server 进程都是由Zygote进程来fork的。也叫做孵化器。它通过linux中的fork形式创建应用程序进程和system_server 。由于zygote进程在启动的时候会创建java虚拟机环境,因此通过fork而创建的应用程序进程或者system_server进程可以在内部获得java虚拟机环境,不需要单独为每一个进程创建java虚拟机环境。

2、Zygote启动脚本

init.rc是以import方式来引入各个模块的rc的,包括前面讲过的bootanimation,surfaceflinger等也是,当然zygote也一样。
路径:system/core/rootdir/init.zygote32.rc
这里有多个zygote.rc那是因为android系统支持64位系统和32位的原因
分析32位这个文件既可以
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
关键即在第一句:
根据前面分析过的bootanimation,大概得知Zygote进程名称为zygote,执行程序为app_process ,class name为main。
所以接下来去分析app_process的源码既可以。
app_process到底代码在哪里呢?一般可以通过framework目录下grep app_process既可以
grep结果如下:
./app_process/Android.mk:45:LOCAL_MODULE:= app_process

代码路径:frameworks/base/cmds/app_process/

3、 app_process中app_main.cpp源码分析

int main(int argc, char* const argv[])
{
      //省略部分
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));//进行AppRuntime的构造
    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;
  //省略。。。
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;//变量zygote设置
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }
	//省略
    Vector<String8> args;
    if (!className.isEmpty()) {
	//省略
        runtime.setClassNameAndArgs(className, argc - i, argv + i);
	//省略
    } else {//省略}

    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }

    if (zygote) {
    	//进入这里进行java类的启动
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }

代码中关键只有2处注释:
AppRuntime的构造,源码可以看出AppRuntime继承AndroidRuntime,故只需要分析AndroidRuntime既可以:

class AppRuntime : public AndroidRuntime
{
public:
    AppRuntime(char* argBlockStart, const size_t argBlockLength)
        : AndroidRuntime(argBlockStart, argBlockLength)
        , mClass(NULL)
    {
    }

接下来属于zygote进程调用runtime.start(“com.android.internal.os.ZygoteInit”, args, zygote);即
AndroidRuntime的start方法

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
   //省略
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) {
    //启动java需要的jvm环境,才可以运行java代码
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
 //省略
    if (startClass == NULL) { //省略
    } else {
      //省略
        if (startMeth == NULL) {
        } else {
            //关键调用对应的"com.android.internal.os.ZygoteInit"类main方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
        }
    }
    //省略
}

上面可以看出app_main主要做的工作就是准备虚拟机环境,让进程运行到了java世界的ZygoteInit的main方法

4、ZygoteInit的源码分析

路径:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java


```cpp
 public static void main(String argv[]) {
 //构造ZygoteServer对象
        ZygoteServer zygoteServer = new ZygoteServer();
//省略

        final Runnable caller;
        try {
//省略
            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } 
                //省略
            }
            //创建SocketServer端
            zygoteServer.registerServerSocket(socketName);
         
            if (!enableLazyPreload) {
       //加载资源
                preload(bootTimingsTraceLog);
            } else {
                Zygote.resetNicePriority();
            }
//省略
            if (startSystemServer) {
                //进入循环等待
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();
                    return;
                }
            }
            //进入永久循环等待请求来创建新的进程
            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            //省略
        } finally {
            zygoteServer.closeServerSocket();
        }
        //省略
        if (caller != null) {
            caller.run();
        }
    }
    主要干了以下几件事情:
    1、创建出server端的socket,接受AMS创建新进程的请求
    2、预加载了类,资源t,opengl,so库等
    3、启动了system_server进程
    4、循环等待AMS请求来创建新的进程
    那Zygote自身启动部分就分析完成,后续文章在分析system server启动及普通app进程的启动

03-19
### ZygoteAndroid系统中的角色 ZygoteAndroid 系统中一个非常重要的原生进程,它作为所有应用进程的父进程存在。所有的应用程序进程都由 Zygote 通过 `fork` 创建出来[^1]。这意味着当一个新的应用程序需要启动时,Zygote 接收到请求并通过复制自身的内存空间来创建新的子进程。 #### Zygote启动流程 Zygote 进程是由 Linux 系统用户空间的第一个进程——init 进程通过 fork 方式创建的。具体来说,在系统的初始化阶段,init 进程会读取配置文件并执行相应的命令以启动 Zygote。这一过程中,Zygote 被指定为 `/system/bin/app_process` 可执行程序,并为其分配了一个 UNIX 域套接字资源用于进程间的通信[^2]。 #### App Process 的启动机制 当 Zygote 启动后,它实际上加载的是 Java 层面的一个核心类 `com.android.internal.os.ZygoteInit`[^3]。此启动类负责完成一系列必要的初始化操作,比如预加载常用的框架库和资源等。之后,Zygote 开始监听来自 ActivityManagerService 的指令,一旦有新任务到来,则依据这些指令利用其已有的虚拟机环境快速分叉出新的子进程[^4]。 #### Virtual Machine 实例化细节 在实际实现层面,每当 Zygote 自身被启动的时候,都会经历如下几个重要环节:首先构建一个名为 AppRuntime 对象;接着调用该对象内的 start 方法;再经由 JNI 技术去建立 JVM 或 ART(取决于设备支持情况)实例;最后运行到 com.android.internal.os.ZygoteInit 类里的 main 函数入口处。如果此时传入了特定标志位表明还需要进一步开启 system server ,那么就会继续沿着这条逻辑链向下处理直至整个 framework layer 完全就绪为止。 ```java public class ZygoteInit { public static void main(String argv[]) throws ZygoteInit.MethodAndArgsCaller{ ... boolean startSystemServer = false; // Parse command line arguments. for (int i=0; i<argv.length; ++i){ if ("--start-system-server".equals(argv[i])) { startSystemServer = true; } } registerZygoteSocket(); runSelectLoop(startSystemServer); } } ``` 上述代码片段展示了如何解析命令行参数以及注册 socket 来准备接收外部连接的部分逻辑。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值