Android FrameWork 之zygote与systemserver 的启动源码分析

上一篇 说了 开机的init 进程,这里说明下zygote 进程 借鉴一下其他大佬的说明

所有的应用程序进程,以及用来运行系统关键服务的System进程都是由zygote进程负责创建的。因此,我们将它称为进程孵化器。

我们看zygote 的源码 主要是通过

http://androidxref.com/6.0.0_r1/xref/frameworks/base/cmds/app_process/app_main.cpp

这个文件 是zygote 的源代码  通过这个cpp 生成可执行文件所以我们直接从它的main 方法 看起

    int main(int argc, char* const argv[])
187{
       ... 
        //创建了一个appRuntime 
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    argc--;
    argv++;


    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;

       //解析传过来的配置参数 
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
                //记录bool 值 startsystemserver 为true 
        } 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;
        }
    }

    if (zygote) {
           //到这里会调用 start 方法传入一个 com.android.internal.os.ZygoteInit 这是一                
           个java 文件名
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {

        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } 
    .......

上面主要是解析参数 创建了一个AppRuntime 最后调用了它的start 方法 然后我们 看一看这个AppRuntime 到底是个什么东西  源码位置 

http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/jni/AndroidRuntime.cpp

我们直接看它的start 

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ... 
    // 到这里开始创建java 虚拟机。。 还有jni的一些初始化
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

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

    //下面的东西 我们应该很熟悉都是jni 的操作。。。 说明我们即将开始进去java 文件了。。。
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;

    // strArray= new String[options.size() + 1];
    stringClass = env->FindClass("java/lang/String");
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    // strArray[0] = "com.android.internal.os.ZygoteInit"
    classNameStr = env->NewStringUTF(className);
    env->SetObjectArrayElement(strArray, 0, classNameStr);

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

    // 其实这个classname 就是我们传入的。。"com/android/internal/os/ZygoteInit"
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);//找到了jclass 对象 
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        // 获取 ZygoteInit.java 的 main方法的methodid 
        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 {
            //调用ZygoteInit 的 main 方法 然后开始调用java 文件了。。
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
        }
    }
    ...
}

上面通过jni 调用了 zygoteinit.java 的main 方法 ,激动人心的java 时刻终于来临 我们看看 ZygoteInit .java 到底长什么样 

源码位置  http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

 public static void main(String argv[]) {
       try {
       		//开启ddms
            RuntimeInit.enableDdms();
            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();

            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true; //找到参数 为 start system server 标记一个bool
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            registerZygoteSocket(socketName);//创建一个zygote 的socket
            preload(); //预加载一些资源 主要是系统的
            。。。。。。。

            // Disable tracing so that forked processes do not inherit stale tracing tags from
            // Zygote.
           Trace.setTracingEnabled(false);
   
           if (startSystemServer) {
                startSystemServer(abiList, socketName);//开启systemserver
            }

            //死循环 等待接受消息 孵化进程
            runSelectLoop(abiList);
            //都完事了 关闭socket
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
           caller.run();
        } catch (RuntimeException ex) {
           Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
           throw ex;
        }
   }

然后我们看看startsystemserver 的这个方法的源码 

 private static boolean startSystemServer(String abiList, String socketName)
           throws MethodAndArgsCaller, RuntimeException {
        /* 配置一些命令 参数用于启动 systemserver  */
        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",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            //设置参数
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
            
            /* 调用zygote 的fork 孵化systemserver进程 (native 方法) */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);//等一会 等进程孵化完毕 
            }

            handleSystemServerProcess(parsedArgs); //处理systemserver 进程相关 
        }

        return true;
    }

这上面就是孵化了systemserver 进程 然后 调用handleSystemserverProcess 方法 我们 接下来看看 handleSystemserverprocess 方法

private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
       closeServerSocket();
        // set umask to 0077 so new files and directories will default to owner-only permissions.
        Os.umask(S_IRWXG | S_IRWXO);
        if (parsedArgs.invokeWith != null) {    、
        //执行application命令 
           WrapperInit.execApplication(parsedArgs.invokeWith,
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(), null, args);
        } else {
        //创建classloader 。。 看看这是什么。。这不是熟悉的pathclassloader 吗。他的父类是systemclassloader
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
                Thread.currentThread().setContextClassLoader(cl); //设置当前线程的classloader 为pathclassloader 
            }
            //最后又整到了 runtimeInit.zygoteinit 方法 
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

  }

我们看看 RuntimeInit   源码位置  http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        nativeZygoteInit();
        
        applicationInit(targetSdkVersion, argv, classLoader);
} 

我们直接看applicaitoninit 方法

 

 private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
           throws ZygoteInit.MethodAndArgsCaller {

    // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

我们接着看看 invokestaticmain 

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;
   try {
   		//反射拿到 class 对象 也就是 systemserver.java
            cl = Class.forName(className, true, classLoader);
        }          ex);
       
       Method m;
        try {
        //拿到它的main 方法
            m = cl.getMethod("main", new Class[] { String[].class });
        }
        //调用 zygoteinit 的methodcaller 方法
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }

又 折腾到了zygoteinit  我们回来看看这个methodandargscaller  方法

 public static class MethodAndArgsCaller extends Exception
           implements Runnable {
        private final Method mMethod;
        private final String[] mArgs;
       public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
            //反射执行 了main 方法 也就是 systemserver 的main 
                mMethod.invoke(null, new Object[] { mArgs });
        }
    }

折腾一圈儿 终于到了SystemServer 了。源码位置  http://androidxref.com/6.0.0_r1/xref/frameworks/base/services/java/com/android/server/SystemServer.java

我们看看它的main 方法做了什么 下面的参考了一个大佬的文章 末尾会附上大佬的博文地址 他 注释的很详细 

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

private void run() {
        try {
        	//开启日志跟踪
            traceBeginAndSlog("InitBeforeStartServices");  
            
            //如果设备时钟在1970之前,则重新赋值为1970
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }

            //如果没有设置时区,默认为格林威治时间(GMT)
            String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
            if (timezoneProperty == null || timezoneProperty.isEmpty()) {
                SystemProperties.set("persist.sys.timezone", "GMT");
            }
            
            //检查设置语言环境
            if (!SystemProperties.get("persist.sys.language").isEmpty()) {
                final String languageTag = Locale.getDefault().toLanguageTag();

                SystemProperties.set("persist.sys.locale", languageTag);
                SystemProperties.set("persist.sys.language", "");
                SystemProperties.set("persist.sys.country", "");
                SystemProperties.set("persist.sys.localevar", "");
            }

            //系统服务器不应该进行非单向调用
            Binder.setWarnOnBlocking(true);
            //系统服务器应该始终加载安全标签
            PackageItemInfo.setForceSafeLabels(true);
            //停用SQLiteCompatibilityWalFlags,直到初始化设置提供程序
            SQLiteCompatibilityWalFlags.init(null);

            //----------此处开始进入Android系统服务-----------
            int uptimeMillis = (int) SystemClock.elapsedRealtime();
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
            if (!mRuntimeRestart) {
                MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
            }

            //如果自上次引导以来运行时发生切换(例如什么时候)在OTA中删除旧的运行时),则设置系统属性,使其同步
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

            //更多内存
            VMRuntime.getRuntime().clearGrowthLimit();

            //系统服务器必须一直运行,因此需要尽可能高效地使用内存。
            VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

            //有些设备依赖于运行时指纹生成,因此在进一步引导之前请确保我们已经定义了它。
            Build.ensureFingerprintProperty();

            //在系统服务器中,在没有显式指定用户的情况下访问环境路径是错误的。
            Environment.setUserRequired(true);

            //在系统服务器中,任何传入的包都应该被解除锁定,以避免抛出BadParcelableException。
            BaseBundle.setShouldDefuse(true);

            //在系统服务器中,当打包异常时,包括堆栈跟踪
            Parcel.setStackTraceParceling(true);

            //确保对系统的绑定调用始终以前台优先级运行。
            BinderInternal.disableBackgroundScheduling(true);

            //增加system_server中绑定器线程的数量
            BinderInternal.setMaxThreads(sMaxBinderThreads);

            //准备创建主线程(当前线程).
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            
            Looper.prepareMainLooper(); //创建主线程
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

            //加载libandroid_servers.so库
            System.loadLibrary("android_servers");

            //检查我们上次试着关闭时是否失败
            performPendingShutdown();

            //初始化系统上下文
            createSystemContext();

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

            //为可以并行化的init任务准备线程池
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();
        }

        //开启系统服务
        try {
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            throw ex;
        } finally {
            traceEnd();
        }

        //......
        
        //开启主线程,进入死循环,处理各种事件消息
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    
	//此处稍微注意,全局上下文是通过ActivityThread创建的
	private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }

以上的run方法大概可以分为下面几步:

  • 首先设置时间、市区、语言等环境,然后设置虚拟机的一些属性参数
  • 然后调用Looper.prepareMainLooper()创建主线程,即我们熟知的UI线程
  • 接着加载android_servers底层库,初始化系统上下文对象
  • 再接着就是初始化各种系统服务,例如:SystemServiceManager、ActivityServiceManager、WifiService等
  • 最后调用Looper.loop()开启死循环,以处理各种事件消息

参考文章 

android zygote进程启动到SystemServer进程启动过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值