美文网首页
Android之zygote源码剖析(二)

Android之zygote源码剖析(二)

作者: Lee_5566 | 来源:发表于2021-03-08 20:11 被阅读0次
image.png

目录

Android之zygote源码剖析(一)
Android之zygote源码剖析(二)
Android之zygote源码剖析(三)
Android之SystemServer介绍(一)
Android之SystemServer介绍(二)
Android之Launcher介绍(一))

c库zygote源码

上文分析了c库的zygote源码,后续调用runtime.start启动虚拟机并进入JAVA部分。

先来看下runtime.start的代码(AndroidRuntime.h)

……
#include <utils/Errors.h>
#include <binder/IBinder.h>
#include <utils/String8.h>
#include <utils/String16.h>
#include <utils/Vector.h>
#include <utils/threads.h>
#include <pthread.h>
#include <nativehelper/jni.h>


namespace android {

class AndroidRuntime
{
public:
……

    /**
     * Call a class's static main method with the given arguments,
     */
    status_t callMain(const String8& className, jclass clazz, const Vector<String8>& args);

    /**
     * Find a class, with the input either of the form
     * "package/class" or "package.class".
     */
    static jclass findClass(JNIEnv* env, const char* className);

    void start(const char *classname, const Vector<String8>& options, bool zygote);

    void exit(int code);

    void setExitWithoutCleanup(bool exitWithoutCleanup) {
        mExitWithoutCleanup = exitWithoutCleanup;
    }

    static AndroidRuntime* getRuntime();

    /**
     * This gets called after the VM has been created, but before we
     * run any code. Override it to make any FindClass calls that need
     * to use CLASSPATH.
     */
    virtual void onVmCreated(JNIEnv* env);
……
};

}

#endif

(AndroidRuntime.cpp):

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ALOGD(">>>>>> START %s uid %d <<<<<<\n",
            className != NULL ? className : "(unknown)", getuid());

    static const String8 startSystemServer("start-system-server");

   // “startSystemServer==true”表示运行时已过时,不能从init.rc中运行,所以我们在这里打印启动事件。
    for (size_t i = 0; i < options.size(); ++i) {
        if (options[i] == startSystemServer) {
           /* track our progress through the boot sequence */
           const int LOG_BOOT_PROGRESS_START = 3000;
           LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
        }
    }

    // 根据环境变量,设置目录
    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }


    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;

    // 启动虚拟机
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    // 为java虚拟机注册JNI方法
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;

    // 调用JNI的方法
    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    assert(strArray != NULL);

    // className == com.android.internal.os.ZygoteInit
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);

    for (size_t i = 0; i < options.size(); ++i) {
        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
        assert(optionsStr != NULL);
        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
    }

    // 将com.android.internal.os.ZygoteInit换成com/android/internal/os/ZygoteInit
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        // 找到ZygoteInit类的main方法
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            // JNI调用JAVA方法,执行ZygoteInit类的main方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
    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");
}

代码中有注释解释。

从上面可以看出之后执行到了ZygoteInit类的main方法(ZygoteInit.java):

    public static void main(String argv[]) {
        // 创建一个ZygoteServer
        ZygoteServer zygoteServer = new ZygoteServer();

        // 启动zygote
        ZygoteHooks.startZygoteNoThreadCreation();

        // Zygote goes into its own process group.
        try {
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }

        try {
            ……

            // 注册socker,名字为zygote
            zygoteServer.registerServerSocket(socketName);
     
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
                // 预加载类和资源
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else {
                Zygote.resetNicePriority();
            }

            SamplingProfilerIntegration.writeZygoteSnapshot();
            bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
            gcAndFinalize();
            bootTimingsTraceLog.traceEnd();

            bootTimingsTraceLog.traceEnd();
            Trace.setTracingEnabled(false);
            Zygote.nativeUnmountStorageOnInit();

            Seccomp.setPolicy();

            ZygoteHooks.stopZygoteNoThreadCreation();

            // 启动系统服务
            if (startSystemServer) {
                startSystemServer(abiList, socketName, zygoteServer);
            }

            Log.i(TAG, "Accepting command socket connections");
            // 执行select,等待AMS发过来创建app请求
            zygoteServer.runSelectLoop(abiList);

            zygoteServer.closeServerSocket();
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
    }

大致分为四步:

  1. 创建zygote服务,并注册socket。
  2. 预加载类和资源。
  3. 系统SystemService进程。
  4. 上面注册的服务等待AMS的请求。
image.png

相关文章

网友评论

      本文标题:Android之zygote源码剖析(二)

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