首先 ,Linux  系统启动的最后一步将读取init.rc这个文件,这个文件我们一般的android手机,Linux内核就是通过这个文件来启动我们的android内核的。


init.rc路径: 根目录下就有

init.rc会启动一个服务,

启动服务的语法如下

Services

services 是一些由init 启动 和 重新(如果有需要)启动的程序,当然这些程序如果是存在的。



services 的格式如下:



service <name> <pathname> [ <argument> ]*
  <option>
  <option>
  ...


-------------------------------------------------------------------------------

service zygote /system/bin/app_process -Xzygote /system/bin –zygote –start-system-server
    socket zygote stream 666
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on


启动一个名为zygote的虚拟机程序Dalvik,位置在system/bin/app_process下,

先来说下几个概念 Dalvik.

在android源码中有几个地方是有涉及到这个,分别是

1.dalvik/dalvikvm

2.dalvik/dvz

3.frameworks/base/cmds/app_process

区别在于dalvikvm是可以用来执行java,它会创建一个虚拟机来执行JAR文件,但这个JAR文件是android用dx工具处理成dex格式的文件。

dvz是已经预装了Framework大部分类和资源的,所以他可以直接用来运行Android的类。

以上2个可能就是个测试工具,真正用到的是第3个


工作流程都是通过JNi传入类的地址和名称,然后FindClass,调用静态方法Main函数,注意,dvz也是调用静态方法Main,而不是create.我们Activity的create方法是Android framework调用的。




第3个就是我们关键的app_process

app_process与上面不同的是,它需要适配framework.

framework在启动时需要加载2个类,分别是ZygoteInit和SystemService这2个类,所以需要用到app_process.  我们来看下具体代码。

if (0 == strcmp("--zygote", arg)) {
            bool startSystemServer = (i < argc) ?
                    strcmp(argv[i], "--start-system-server") == 0 : false;
            setArgv0(argv0, "zygote");
            set_process_name("zygote");
            runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer);
        } else {
            set_process_name(argv0);

            runtime.mClassName = arg;

            // Remainder of args get passed to startup class main()
            runtime.mArgC = argc-i;
            runtime.mArgV = argv+i;

            LOGV("App process is starting with pid=%d, class=%s.\n",
                 getpid(), runtime.getClassName());
            runtime.start();
        }

以上代码是在app_process的app_main.cpp里的main函数里的,启动app_process会执行到,如何启动呢?

看上面init.rc的参数,

service      zygote    /system/bin/app_process -Xzygote                      /system/bin         –zygote                                 –start-system-server
启动服务    名称       路径                                  虚拟机启动的参数       服务路径             是否需要启动Zygoteinit        是否需要启动  systemservice

然后来看那个

  runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer);



这个代码也是会通过classname加载ZygoteInit的main函数,然后main函数又去做了一系列的动作,



public static void main(String argv[]) {
        try {
            VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);

            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();

            registerZygoteSocket();       //注册一个,启动socket服务端
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preloadClasses();      //加载framework jar
            //cacheRegisterMaps();
            preloadResources();   //加载系统资源
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());

            // Finish profiling the zygote initialization.
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // Do an initial gc to clean up after startup
            gc();

            // If requested, start system server directly from Zygote
            if (argv.length != 2) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

            if (argv[1].equals("true")) {
                startSystemServer();    //启动systemservice进程,这个是zygote孵化出的第一个进程,采用fork机制
            } else if (!argv[1].equals("false")) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

            Log.i(TAG, "Accepting command socket connections");

            if (ZYGOTE_FORK_MODE) {
                runForkMode();
            } else {
                runSelectLoopMode();   开启select机制监听文件标示符。
            }

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



他的 main方法主要做3件事,

一 : 启动服务端socket 口,linux的select 机制,服务器端sokect是通过 Zygoteconnection的runonce来处理来自客户端Socket的各种请求,理论上,可以有多个客户端socket口,但必须只有一个服务器端Socket口。

接受到客户端指令后,就去fork一个新的进程。这样就启动了我们的客户端了哦,


二:有了服务器端口,我们还必须要有资源和必要的class文件,

关于fork,他其实就是拷贝了一份当前的进程,除了进程ID不一样,其他包括共享内存都一样,为什么要fork呢,因为他们共享了以大堆framework自带的资源和JAVA文件


fork 过程调用的都是Linux 内核层,所以可能是父进程和子进程 ,fork有返回值,返回pid =0 表示子进程,返回大于0则是父进程,

如果是子进程的话,我们还需要做一步操作,就是关闭服务器端的socket,因为我们只需要一个卵进程来孵化新进程,而不是子孵化子。

于是我们定位到了 zygoteconnection里的runonce方法,这个是select文件标示符返回正确时执行得。


try {
            parsedArgs = new Arguments(args);

            applyUidSecurityPolicy(parsedArgs, peer);
            applyDebuggerSecurityPolicy(parsedArgs);
            applyRlimitSecurityPolicy(parsedArgs, peer);
            applyCapabilitiesSecurityPolicy(parsedArgs, peer);

            int[][] rlimits = null;

            if (parsedArgs.rlimits != null) {
                rlimits = parsedArgs.rlimits.toArray(intArray2d);
            }

            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, parsedArgs.debugFlags, rlimits);
        } catch (IllegalArgumentException ex) {
            logAndPrintError (newStderr, "Invalid zygote arguments", ex);
            pid = -1;
        } catch (ZygoteSecurityException ex) {
            logAndPrintError(newStderr,
                    "Zygote security policy prevents request: ", ex);
            pid = -1;
        }

        if (pid == 0) {
            // in child
            handleChildProc(parsedArgs, descriptors, newStderr);   //需要关闭服务端端口。
            // should never happen
            return true;
        } else { /* pid != 0 */
            // in parent...pid of < 0 means failure
            return handleParentProc(pid, descriptors, parsedArgs);
        }



三 启动systemservice 创建我们的客户端。

有了服务器端,没人去调用,怎么去孵化新进程呢,在一切准备完毕后,ZygoteInit的Main函数里会调用startSystemService来启动


String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
            "--capabilities=130104352,130104352",
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);

            /*
             * Enable debugging of the system process if *either* the command line flags
             * indicate it should be debuggable or the ro.debuggable system property
             * is set to "1"
             */
            int debugFlags = parsedArgs.debugFlags;
            if ("1".equals(SystemProperties.get("ro.debuggable")))
                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, debugFlags, null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }



代码如下,根据args数组,启动了

com.android.server.SystemServer 类的main函数。

SystemServer是Android系统的神经中枢,我们需要利用到Android系统的大部分功能都在该进程中进行。Ams,Wms,Pms都是以线程在这个进程中运行的,他们一起协同工作。

SystemServer的Main方法会调用一个init1(),然后会回调本类的init2(),在该方法里启动了一个ServerThread对象,里面的run方法启动了很多的服务,而且启动的方式都不同,我们主要关注AMS的启动和一些初始化。


接下来我们来看下AMS 的用处,比较关键,