android启动--深入理解zygote

来源:互联网 发布:金坷垃 知乎 编辑:程序博客网 时间:2024/05/02 02:28

http://www.2cto.com/kf/201203/123062.html


前一篇http://www.2cto.com/kf/201203/123061.html文章介绍了init进程的启动过程,其中就有解析init.rc脚本,而根据其内容配置启动了很多重要的服务:Servicemanager和zygote进程就奠定了Android的基础,建立了真正的android空间。

 进程名称               进程路径

zygote                 /system/bin/app_process

servicemanager   /system/bin/servicemanager

bootanim            /system/bin/bootanimation

media                 /system/bin/mediaserver

...

这里还都是在native世界中,此层分析哪个service没有启动,则找到相关的进程加打印即可,比较好分析,成功启动的进程利用ps命令即可查看。

说明一下android中的两个不同世界:

JAVA世界:运行基于 dalvik 虚拟机的 JAVA 程序

NATIVE世界:利用 C或C++开发的程序组成native世界。

下面开始分析 zygote 启动流程:

代码路径:frameworks\base\cmds\app_process

启动参数:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

int main(int argc, const char* const argv[])

{

    // These are global variables in ProcessState.cpp

    mArgC = argc;

    mArgV = argv;

    // Next arg is startup classname or "--zygote"

    if (i < argc) {

        arg = argv[i++];

        if (0 == strcmp("--zygote", arg)) {   // init.rc 中的参数值

bool startSystemServer = (i < argc) ?

strcmp(argv[i], "--start-system-server") == 0 : false;

setArgv0(argv0, "zygote");

set_process_name("zygote");   // 利用prctl修改进程名称

 runtime.start("com.android.internal.os.ZygoteInit",

startSystemServer);   // 这就是真正的重点!!!!
        }

....

}

下面开始建立 AndroidRuntime : 

路径:frameworks\base\core\jni

class AppRuntime : public AndroidRuntime

AppRuntime  重载实现了 onStarted() , onZygoteInit(), onExit() 函数

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

-->  调用

/*

 * Start the Android runtime.  This involves starting the virtual machine

 * and calling the "static void main(String[] args)" method in the class

 * named by "className".

 */

void AndroidRuntime::start(const char* className, const bool startSystemServer)

{

 // 基本上再次看到这句话,说明系统重启了

LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");

 


// 1、启动 虚拟机

/* start the virtual machine */

 if (startVm(&mJavaVM, &env) != 0)

        goto bail;

 


// 2、注册 jni 函数

/*

* Register android functions.

 */

if (startReg(env) < 0) {

LOGE("Unable to register all android natives\n");

goto bail;

}

/*

 3、从 com.android.internal.os.ZygoteInit 类中找到main函数,即调用

 ZygoteInit.java类中的main, 此时将进入到 java 世界。。。。

 */

startMeth = env->GetStaticMethodID(startClass, "main",

 "([Ljava/lang/String;)V");
 env->CallStaticVoidMethod(startClass, startMeth, strArray);

}

 


欢迎来到 JAVA 世界。。。。。

下面直接分析 ZygoteInit 类中的 main 函数:

路径: frameworks\base\core\java\com\android\internal\os

public static void main(String argv[]) {

//1 、建立端口号为 50 的监听套接字,用于接收

//    ActivityManangerService 的请求,Fork应用程序

registerZygoteSocket();

// 2、预加载类和资源,优化代码时这里可以想点办法,不过有点麻烦

preloadClasses();

// 3、垃圾回收

gc();

// 4、启动 SystemServer ,这个下面再重点讲解

startSystemServer();

// 5、处理客户连接与请求,具体由 ZygoteConnection.runOnce()处理

runSelectLoopMode();

...

}

 


SystemServer 的分析:

这个进程是由 zygote 产生的第一个进程

/**

* Prepare the arguments and fork for the system server process.

*/

private static boolean startSystemServer()

{

...

/* Hardcoded command line to start the system server */

String args[] = {

      "--setuid=1000",

      "--setgid=1000",            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",

      "--capabilities=130104352,130104352",

      "--runtime-init",

      "--nice-name=system_server",        // process name  

      "com.android.server.SystemServer",   // class name

};

// 解析参数

parsedArgs = new ZygoteConnection.Arguments(args);

/* Request to fork the system server process */

pid = Zygote.forkSystemServer(

             parsedArgs.uid, parsedArgs.gid,

                    parsedArgs.gids, debugFlags, null);

/* For child process */

if (pid == 0) {

       handleSystemServerProcess(parsedArgs); // 后面讲述

}

}

-->

forkSystemServer 这是一个jni 函数,调用:

\dalvik\vm\native\dalvik_system_Zygote.c 下面

static void Dalvik_dalvik_system_Zygote_forkSystemServer(

        const u4* args, JValue* pResult)

{

pid_t pid;

// 根据参数fork 出一个子进程,若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1

pid = forkAndSpecializeCommon(args);

if(pid > 0) {

gDvm.systemServerPid = pid;

        /* There is a slight window that the system server process has crashed

         * but it went unnoticed because we haven't published its pid yet. So

         * we recheck here just to make sure that all is well.

         */

        if (waitpid(pid, &status, WNOHANG) == pid) {

            LOGE("System server process %d has died. Restarting Zygote!", pid);

            kill(getpid(), SIGKILL);

        }

/*

这里表示SystemServer进程退出,而其父进程是Zygote,所以这里 kill掉的就是Zygote进程,即两者都退出了。。。。

*/

}

}

 


Zygote 与 SystemServer 关系非常紧密,这里有个小处理逻辑:

static pid_t forkAndSpecializeCommon(const u4* args)

{

setSignalHandler(); 

}

-->

static void setSignalHandler()

{

    int err;

    struct sigaction sa;

    memset(&sa, 0, sizeof(sa));

    sa.sa_handler = sigchldHandler; // 在此安装了一个信号处理函数

    err = sigaction (SIGCHLD, &sa, NULL);

    ...

}

信号处理函数:

/*

 * This signal handler is for zygote mode, since the zygote

 * must reap its children

 */

static void sigchldHandler(int s)

{

    pid_t pid;

    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {

        /*

         * If the just-crashed process is the system_server, bring down zygote

         * so that it is restarted by init and system server will be restarted

         * from there.

         */

        if (pid == gDvm.systemServerPid) {

            LOG(LOG_INFO, ZYGOTE_LOG_TAG,

                "Exit zygote because system server (%d) has terminated\n",

                (int) pid);

            kill(getpid(), SIGKILL);

        }

}

...

}

 


Zygote 启动流程内容太多,下一篇从handleSystemServerProcess 处理流程讲解


使用 Zygote.forkSystemServer 利用 fork 生成 SystemServer进程,那个这个进程到底干了哪些事情呢?

下面从 handleSystemServerProcess 处理流程开始讲解

代码片段如下:

/* Request to fork the system server process */

pid = Zygote.forkSystemServer(

                    parsedArgs.uid, parsedArgs.gid,

                    parsedArgs.gids, debugFlags, null);

/* For child process */

if (pid == 0) {

      handleSystemServerProcess(parsedArgs);

}

-->

private static void handleSystemServerProcess(

ZygoteConnection.Arguments parsedArgs)

{

// 关闭哪些从 Zygote 继承来的 socket

closeServerSocket();

// 这里调用到 zygoteInit函数

RuntimeInit.zygoteInit(parsedArgs.remainingArgs);

}

RuntimeInit.java @ frameworks\base\core\java\com\android\internal\os

public static final void zygoteInit(String[] argv){

// 这里调用到 JNI 函数中去了

zygoteInitNative();

// 调用到startClass com.android.server.SystemServer 的main函数

invokeStaticMain(startClass, startArgs);

}

-->

zygoteInitNative @ frameworks\base\core\jni

调用到 onZygoteInit @frameworks\base\cmds\app_process\app_main.cpp

    virtual void onZygoteInit()

    {

        sp<ProcessState> proc = ProcessState::self();

        if (proc->supportsProcesses()) {

            LOGV("App process: starting thread pool.\n");

            proc->startThreadPool(); // 启动线程,建立 binder 通讯

        }

}

ok, 这个流程清楚了,下面我们重点看看 native system_server进程如何启动?

Main @ frameworks\base\services\java\com\android\server\SystemServer.java

public static void main(String[] args) {

System.loadLibrary("android_servers");

init1(args);

}

这里 init1 是个 native 函数:

system_init @ frameworks\base\cmds\system_server\library\system_init.cpp

extern "C" status_t system_init()

{

LOGI("Entered system_init()");

// Start the SurfaceFlinger

SurfaceFlinger::instantiate();

runtime->callStatic("com/android/server/SystemServer", "init2");

...

}

这里又调用到

init2 @ frameworks\base\services\java\com\android\server\SystemServer.java

public static final void init2() {

Thread thr = new ServerThread();

thr.setName("android.server.ServerThread");

thr.start();

}

这里启动了一个 ServerThread 线程并调用其start() 函数,其实也就是调用

ServerThread 线程的 run() 函数

public void run() {

     Slog.i(TAG, "Entropy Service");

     ServiceManager.addService("entropy", new EntropyService());

     Slog.i(TAG, "Power Manager");

     power = new PowerManagerService();

     ServiceManager.addService(Context.POWER_SERVICE, power);

...

 // 最后进入到 loop 消息循环中处理消息了。。。。

        Looper.loop();

        Slog.d(TAG, "System ServerThread is exiting!");

}

Oh , 原来就是在就里将很多重要的系统服务依次加入到ServiecManager中,至此整个 SystemServer 进程启动完成。

 


总结一下,重要执行过程如下:

\

原创粉丝点击