专栏名称: foxleezh
android工程师
目录
相关文章推荐
天津日报  ·  水上公园官宣:免费发! ·  12 小时前  
天津日报  ·  钟南山:不要慌! ·  昨天  
人力资源管理  ·  如何构建有效的招聘体系? ·  2 天前  
天津日报  ·  连续三天,35℃+!天津发布预警 ·  2 天前  
人力资源数据分析  ·  06/21-22 上海 ... ·  2 天前  
51好读  ›  专栏  ›  foxleezh

Android M系统启动流程

foxleezh  · 简书  ·  · 2017-07-23 18:57

正文

请到「今天看啥」查看全文


zygote进程意为孵化,可以理解为我们的app就是一个个小鸡,这些小鸡都是从zyogte进程孵化出来的,从这个进程开始,我们将从C++的世界切换到java的世界

step 9.main

app_process进程的入口是( /frameworks/base/cmds/app_process/app_main.cpp )的main方法

int main(int argc, char* const argv[])
{
    ...
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    ...
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
       ...
    }
}

这里先new了一个实例AppRuntime ,什么?哪里new了,我没看到new啊,这又是java人看不懂的,C++中有一种实例化方式是这样的A a(args,args);这个相当于A a=new A(args,args)。接着调用runtime.start

step 10.runtime=new AndroidRuntime

前一步的AppRuntime其实是AndroidRuntime的子类

step 11.runtime.start

这步调用的是AndroidRuntime.cpp( frameworks/base/core/jni/AndroidRuntime.cpp )的start方法

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ...
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    ...
    jclass startClass = env->FindClass(slashClassName);
    ...
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
    ...
    env->CallStaticVoidMethod(startClass, startMeth, strArray);
    ...
}

start方法先启动了虚拟机,正式从C++的环境切换到了java虚拟机的环境,我们看到了熟悉的JNI方法

step 12.startVm

这步是启动虚拟机,虚拟机内部实现比较复杂,本文就不展开了

step 13.CallStaticVoidMethod(ZygoteInit,main)

这些方法比较熟悉,Findclass("ZygoteInit")找到ZygoteInit.java类,GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");得到main方法,CallStaticVoidMethod(startClass, startMeth, strArray);调用main方法

小结

步骤9-13主要是启动了Zygote进程,然后在进程中实例化了Java的虚拟机,进入到Java运行环境

step 14.main

通过JNI层的CallStaticVoidMethod方法,调用了ZygoteInit.java( frameworks/base/core/java/com/android/internal/os/ZygoteInit.java )的main方法

public static void main(String argv[]) {
          ...
          try {
            registerZygoteSocket(socketName);
          ...
            preload();
          ...
            if (startSystemServer) {
                startSystemServer(abiList, socketName);
          ...
          } catch (MethodAndArgsCaller caller) {
            caller.run();
          }
          ...
    }

首先注册socket监听,socket名字为“zygote”,用于接受子进程创建req,然后调用preload方法做一些初始化的操作,然后启动SystemServer,注意这里有个try catch语句,之后代码会主动抛出MethodAndArgsCaller异常,然后调用caller.run();

step 15.registerZygoteSocket

private static void registerZygoteSocket(String socketName) {
        if (sServerSocket == null) {
           ...
            try {
                FileDescriptor fd = new FileDescriptor();
                fd.setInt$(fileDesc);
                sServerSocket = new LocalServerSocket(fd);
            } 
          ...
        }
    }

new一个LocalServerSocket的实例并返回给sServerSocket,用于子进程与zygote进程之间的通信

16.preload

static void preload() {
        Log.d(TAG, "begin preload");
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "BeginIcuCachePinning");
        beginIcuCachePinning();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses");
        preloadClasses();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources");
        preloadResources();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
        preloadOpenGL();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        preloadSharedLibraries();
        preloadTextResources();
        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
        // for memory sharing purposes.
        WebViewFactory.prepareWebViewInZygote();
        endIcuCachePinning();
        warmUpJcaProviders();
        Log.d(TAG, "end preload");
    }

加载一些系统资源,OpenGL等

step 17.startSystemServer

private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        ...
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ...

        handleSystemServerProcess(parsedArgs);
       
    }

直接交给handleSystemServerProcess处理







请到「今天看啥」查看全文