美文网首页
深入了解Android读书笔记——深入理解zygote

深入了解Android读书笔记——深入理解zygote

作者: 新一代螺丝工 | 来源:发表于2022-09-28 20:52 被阅读0次

zygote概述

zygote是由init进程通过解析init.zygote.rc文件创建的。应用程序的进程和java虚拟机的启动是由它负责创建和启动的。

启动zygote

init进程解析的zygote文件是system/core/rootdir/init.zygote64_32.rc。init进程解析rc文件获取Service对象(定义在system/core/init/service.h中),调用system/core/init/service.cpp中的start方法启动 zygote 服务。

由于start方法是通过forkexec来启动进程的,由此可知,zygote 的启动方式是 fork + exec

zygote启动过程

zygote所对应的可执行程序app_process,所对应的源文件是frameworks/base/cmds/app_process/app_main.cpp,进程名为zygote。

//传入的参数是 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
int main(int argc, char* const argv[])
{
    ...
    
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // 忽略第一个参数
    argc--;
    argv++;

    ...

    // 参数解析
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i; 
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            //对于64位系统nice_name为zygote64; 32位系统为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;
        }
    }

   ...

    //将进程名设置为 zygote
    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }
    
    if (zygote) {
        // 调用AppRuntime的start方法
        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.");
    }
}

AppRuntime

AppRuntime的定义和声明都在frameworks/base/cmds/app_process/app_main.cpp中。它继承AndroidRuntime,重载了onStartonZygoteInitonExit函数。调用的start函数是 AndroidRuntime 中定义的,代码位置在 frameworks/base/core/jni/AndroidRuntime.cpp

//className 是 com.android.internal.os.ZygoteInit
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
   
    ...


    //创建java虚拟机
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    onVmCreated(env);

    //jni方法注册
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    ...

    //将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit"
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
        } else {
            //调用 ZygoteInit.main 方法,正式进入java世界
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
        }
    }
    //释放相应对象的内存空间
    free(slashClassName);

    ALOGD("Shutting down VM\n");
    if (mJavaVM->DetachCurrentThread() != JNI_OK)
        ALOGW("Warning: unable to detach main thread\n");
    if (mJavaVM->DestroyJavaVM() != 0)
        ALOGW("Warning: VM did not shut down cleanly\n");
}        

startVm

创建java虚拟机,主要工作是关于虚拟机参数的设置

startReg

int AndroidRuntime::startReg(JNIEnv* env)
{
    ATRACE_NAME("RegisterAndroidNatives");
    
    //设置线程创建方法为javaCreateThreadEtc
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    ALOGV("--- registering native functions ---\n");

    /*
     * Every "register" function calls one or more things that return
     * a local reference (e.g. FindClass).  Because we haven't really
     * started the VM yet, they're all getting stored in the base frame
     * and never released.  Use Push/Pop to manage the storage.
     */
    env->PushLocalFrame(200);

    //注册JNI函数
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);

    //createJavaThread("fubar", quickTest, (void*) "hello");

    return 0;
}

ZygoteInit

通过上面的调用,最后走到java层的frameworks/base/core/java/com/android/internal/os/ZygoteInit.java类的main方法

    @UnsupportedAppUsage
    public static void main(String[] argv) {
        
        ZygoteServer zygoteServer = null;

        ...

        Runnable caller;
        try {    
        ...
            if (!enableLazyPreload) {
                ...
                //预加载资源        
                preload(bootTimingsTraceLog);
                ...
            }

            //执行垃圾回收
            gcAndFinalize();
            //用于zygote进程的socket服务
            zygoteServer = new ZygoteServer(isPrimaryZygote);

            if (startSystemServer) {
                //启动SystemServer
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

               ...
            }

            //开启循环等待和处理 socket 请求
            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with fatal exception", ex);
            throw ex;
        } finally {
            if (zygoteServer != null) {
                zygoteServer.closeServerSocket();
            }
        }

        //SystemServer相关
        if (caller != null) {
            caller.run();
        }
    }

预加载资源

    static void preload(TimingsTraceLog bootTimingsTraceLog) {
        ...
        // 预加载 /system/etc/preloaded-classes 文件里面定义的常用类(比如我们用到的 Activity,Fragment 等)
        preloadClasses();
        ...
        // 预加载系统资源
        preloadResources();
        ...
        // 硬件抽象层
        nativePreloadAppProcessHALs();
        ...
        //图像驱动
        maybePreloadGraphicsDriver();
        ...
        //库资源
        preloadSharedLibraries();
        ...
        //语言相关文本信息
        preloadTextResources();
        ...
        //webview
        WebViewFactory.prepareWebViewInZygote();
        ...
    }

预加载的作用

  1. Android通过 zygote fork 的方式创建子进程。zygote预先加载的类和资源在fork时会复制到子进程中,这样就减少了子进程加载资源的时间
  2. forkcopy-on-write机制在子进程不改变父进程的类时,会与父进程共享这部分数据,从而节省内存

创建socket服务

预加载完成后,会通过ZygoteServer创建socket服务,由此可见zygote是通过socket通信的

启动SystemServer

zygote创建socket服务后,会通过fork启动SystemServer进程。

开启循环等待和处理 socket 请求

zygote通过runSelectLoop方法开启循环等待和处理 socket 请求。客户端用ZygoteConnection来表示,客户端的请求则由它的processCommand方法来处理。

总结

image.png

SystemServer

从上面我们知道SystemServer是通过forkSystemServer来启动的,其内部会一直调用到Zygote#forkSystemServe,到frameworks/base/core/jni/com_android_internal_os_Zygote.cpp的
com_android_internal_os_Zygote_nativeForkSystemServer方法。当SystemServer创建失败时,会重启zygote

当进程创建成功时,会先关闭父进程zygote复制而来的Socket,再调用ZygoteInit#handleSystemServerProcess方法

    private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
        
        ...
        if (parsedArgs.mNiceName != null) {
            Process.setArgV0(parsedArgs.mNiceName);//设置进程名字为system_server
        }

        ...

        if (parsedArgs.mInvokeWith != null) {
            
            ...
            //启动应用程序
            WrapperInit.execApplication(parsedArgs.mInvokeWith,
                    parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(), null, args);

            throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
        } else {
            ClassLoader cl = getOrCreateSystemServerClassLoader();
            if (cl != null) {
                Thread.currentThread().setContextClassLoader(cl);
            }

            //启动SystemServer
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, cl);
        }
    }

ZygoteInit的zygoteInit的方法如下

    public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        ...
        RuntimeInit.redirectLogStreams();//重定向log输出

        RuntimeInit.commonInit();//通用的一些初始化
        ZygoteInit.nativeZygoteInit();//与Binder系统建立联系
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }

RuntimeInit的applicationInit方法如下

    protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        ...
        //最后调用了 findStaticMain
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }
    
    protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class<?> cl;

    ...
    //创建MethodAndArgsCaller
    return new MethodAndArgsCaller(m, argv);
}

static class MethodAndArgsCaller implements Runnable {

    public void run() {
        try {
            // 调用 com.android.server.SystemServer 的 main()
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
        } catch (InvocationTargetException ex) {
        }
    }
}

com.android.server.SystemServermain 方法很简单,就是调用 SystemServer 他自己的 run 方法

    public static void main(String[] args) {
        new SystemServer().run();
    }

run 方法如下

    private void run() {
        try {
            ...
            //准备Looper
            Looper.prepareMainLooper();
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

            // 加载 android_servers.so 库
            //该库包含的源码位于 frameworks/base/services/core/jni 下
            System.loadLibrary("android_servers");

            ...

            // 创建 system context.
            createSystemContext();

            // 创建 SystemServiceManager
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setStartInfo(mRuntimeRestart,
                    mRuntimeStartElapsedTime, mRuntimeStartUptime);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            ...
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        // 启动服务
        try {
            ...
            //启动引导服务
            startBootstrapServices();
            //启动核心服务
            startCoreServices();
            //启动其他服务
            startOtherServices();
            ...
        } catch (Throwable ex) {
            ...
        } finally {
            traceEnd();
        }

        ...
        
        // 进入 loop() 循环等待和处理请求
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

参考

https://www.jianshu.com/p/c1ee303620c0
https://www.jianshu.com/p/ce686a88e3bc

相关文章

网友评论

      本文标题:深入了解Android读书笔记——深入理解zygote

      本文链接:https://www.haomeiwen.com/subject/uxthartx.html