Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1372506
  • 博文数量: 478
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4833
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-28 11:12
文章分类

全部博文(478)

文章存档

2019年(1)

2018年(27)

2017年(21)

2016年(171)

2015年(258)

我的朋友

分类: Android平台

2015-10-19 09:32:11

http://blog.csdn.net/xieqibao/article/details/6581975

Android 之 zygote 与进程创建

分类: Android 12211人阅读 评论(5) 收藏 举报

    在android中,应用程序的入口是ActivityThead中的main函数,那么之后系统是怎样为应用程序创建进程的呢?SystemService又是怎样创建的?答案是:zygote

    zygote翻译成中文是受精卵的意思,名字比较奇怪、但是很有意思。在android中,大部分的应用程序进程都是由zygote来创建的,为什么用大部分,因为还有一些进程比如系统引导进程、init进程等不是有zygote创建的。相反,zygote还是在init进程之后才被创建的。在android中提到zygote,主要两块,一个是C/C++编写的zygote,主要用来为应用和SystemService fork进程的。一个是java编写的zygote接口,负责为应用和service调用C/C++ zygote的接口执行fork,从而创建VM进程。说明:在android中,service主要有NativeService和SystemService。SystemService主要是指系统中service,比如,InputMethodService、ActivityManagerService等。

    zygote在android中主要有两个作用:

  1. 建立运行时环境并启动虚拟机,执行com.android.internal.os.ZygoteInit的main函数,从而fork SystemService

  2. [java] view plaincopy
    1. runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);  


  3. 为应用程序创建DVM进程。
  4. 启动SystemServer:

    我们来看看zygote是怎样创建SystemService进程的。在../base/cmds/app_process/app_main.cpp的主函数中,有这样一段代码,它执行了

    runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);   //runtime继承自AndroidRuntime

    也就是说,在主函数中,初始化了运行时环境,并且建立虚拟机,然后运行再com.android.internal.os.ZygoteInit的main函数

    再来看看com.android.internal.os.ZygoteInit的main中都做了哪些事情。在看ZygoteInit之前,有必要先来看下相关的类,类图如下:

     

    在ZygoteInit的main函数中,主要执行了:


    [java] view plaincopy
    1. registerZygoteSocket();//登记Listen端口  
    2. startSystemServer();//启动SystemServer  


    startSystemServer()调用Zygote的native方法 forkSystemServer(); 到这里,java端的Zygote的准备工作就结束了,接下来就交给C/C++端的Zygote来执行fork任务了。来看下代码:

    在 ../dalvik/vm/native/dalvik_system_Zygote.c 中


    [java] view plaincopy
    1. static void Dalvik_dalvik_system_Zygote_forkSystemServer(  
    2. const u4* args, JValue* pResult)  
    3. {  
    4.     pid_t pid;  
    5.     /*调用forkAndSpecializeCommon,执行fork  */  
    6.     pid = forkAndSpecializeCommon(args, true);  
    7.     /* 检查fork后返回的进程pid */  
    8.     if (pid > 0) {  
    9.         int status;  
    10.         LOGI("System server process %d has been created", pid);  
    11.         gDvm.systemServerPid = pid;  
    12.         if (waitpid(pid, &status, WNOHANG) == pid) {  
    13.             LOGE("System server process %d has died. Restarting Zygote!", pid);  
    14.             kill(getpid(), SIGKILL);  
    15.         }  
    16.     }  
    17.     RETURN_INT(pid);  
    18. }  


    在这个里面的fork进程主要是使用linux的fork进程。

    经过这样的过程SystemServer进程就创建起来了。android中的所有服务循环框架都是建立咋SystemServer上,接下来在SystemServer上,就可以建立所有系统服务。可参看:SystemServer.main();

    系统服务启动后会调用ActivityManagerService的systemReady方法,并最终启动HomeActivity。

    启动应用进程:

    我们在上一篇介绍ActivityThread和ActivityManagerService时已经讲过,程序的主入口是在ActivityThread的main函数,activity的startActivity最终是在ActivityManagerService中执行的,那么应用程序的进程是怎么创建的?看下类图:

     

     

    我们再来看看ActivityManagerService中的startProcessLocked方法。


    [java] view plaincopy
    1. int pid = Process.start("android.app.ActivityThread",  
    2.                     mSimpleProcessManagement ? app.processName : null, uid, uid,  
    3.                     gids, debugFlags, null);  


    通过Process的start方法来创建进程。

    [java] view plaincopy
    1. / **  
    2.   *通过Zygote进程来创建新的vm进程  
    3.   */  
    4.   
    5.   public static final int start(final String processClass,final String niceName,int uid, int gid, int[] gids,int debugFlags,String[] zygoteArgs)  
    6.   {  
    7.       if (supportsProcesses()) {  
    8.           try {  
    9.               return startViaZygote(processClass, niceName, uid, gid, gids,  
    10.                       debugFlags, zygoteArgs);     //argsForZygote.add("--runtime-init")初始化运行环境  
    11.           } catch (ZygoteStartFailedEx ex) {  
    12.               Log.e(LOG_TAG,  
    13.                       "Starting VM process through Zygote failed");  
    14.               throw new RuntimeException(  
    15.                       "Starting VM process through Zygote failed", ex);  
    16.           }  
    17.   
    18.       } else {  
    19.   
    20.           // Running in single-process mode  
    21.           Runnable runnable = new Runnable() {  
    22.                       public void run() {  
    23.                           Process.invokeStaticMain(processClass);  
    24.                       }  
    25.           };  
    26.           // Thread constructors must not be called with null names (see spec).  
    27.           if (niceName != null) {  
    28.               new Thread(runnable, niceName).start();  
    29.           } else {  
    30.               new Thread(runnable).start();  
    31.           }  
    32.           return 0;  
    33.       }  
    34.   }  


    在ZygoteConnection中获取套接字连接,并解析启动参数。来看下runOnce方法:

     从LocalSocket. mSocket中解析参数

    [java] view plaincopy
    1. try {  
    2.           args = readArgumentList();  
    3.           descriptors = mSocket.getAncillaryFileDescriptors();  
    4.       } catch (IOException ex) {  
    5.           Log.w(TAG, "IOException on command socket " + ex.getMessage());  
    6.           closeSocket();  
    7.           return true;  
    8.       }  


  5. 调用Zygote的native方法forkAndSpecialize,执行进程的创建工作。本地方法的实现也是在 ../dalvik/vm/native/dalvik_system_Zygote.c 中,底层调用linux的fork。

  6. [java] view plaincopy
    1. pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,  
    2.   
    3.                     parsedArgs.gids, parsedArgs.debugFlags, rlimits);  


    这样应用程序的进程就创建起来了。从ActivityManagerService开始的时序图如下:

     

    总结:

  7. 在android中SystemService的启动是在Zygote进程创建好后进行的,并且由Zygote进程建立好DVM运行环境,加载ZygoteInit的main函数,最终调用Zygote的本地方法forkSystemServer,并执行linux的fork方法创建SystemServer进程。
  8. 应用程序的进程也是由Zygote创建的,在ActivityManagerService中的startProcessLocked中调用了Process.start()方法。并通过连接调用Zygote的native方法forkAndSpecialize,执行fork任务。
  9. 应用进程和服务进程位于不同的进程中,他们之间是通过IPC进行数据传递的。接下来一篇会介绍在android中的进程间通信机制:Binder
阅读(400) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~