在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

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

  2. 为应用程序创建DVM进程。

    启动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 plain copy
    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 plain copy
    1. staticvoidDalvik_dalvik_system_Zygote_forkSystemServer(
    2. constu4*args,JValue*pResult)
    3. {
    4. pid_tpid;
    5. /*调用forkAndSpecializeCommon,执行fork*/
    6. pid=forkAndSpecializeCommon(args,true);
    7. /*检查fork后返回的进程pid*/
    8. if(pid>0){
    9. intstatus;
    10. LOGI("Systemserverprocess%dhasbeencreated",pid);
    11. gDvm.systemServerPid=pid;
    12. if(waitpid(pid,&status,WNOHANG)==pid){
    13. LOGE("Systemserverprocess%dhasdied.RestartingZygote!",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 plain copy
    1. intpid=Process.start("android.app.ActivityThread",
    2. mSimpleProcessManagement?app.processName:null,uid,uid,
    3. gids,debugFlags,null);

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

    [java] view plain copy
    1. /**
    2. *通过Zygote进程来创建新的vm进程
    3. */
    4. publicstaticfinalintstart(finalStringprocessClass,finalStringniceName,intuid,intgid,int[]gids,intdebugFlags,String[]zygoteArgs)
    5. {
    6. if(supportsProcesses()){
    7. try{
    8. returnstartViaZygote(processClass,niceName,uid,gid,gids,
    9. debugFlags,zygoteArgs);//argsForZygote.add("--runtime-init")初始化运行环境
    10. }catch(ZygoteStartFailedExex){
    11. Log.e(LOG_TAG,
    12. "StartingVMprocessthroughZygotefailed");
    13. thrownewRuntimeException(
    14. "StartingVMprocessthroughZygotefailed",ex);
    15. }
    16. }else{
    17. //Runninginsingle-processmode
    18. Runnablerunnable=newRunnable(){
    19. publicvoidrun(){
    20. Process.invokeStaticMain(processClass);
    21. }
    22. };
    23. //Threadconstructorsmustnotbecalledwithnullnames(seespec).
    24. if(niceName!=null){
    25. newThread(runnable,niceName).start();
    26. }else{
    27. newThread(runnable).start();
    28. }
    29. return0;
    30. }
    31. }

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

    从LocalSocket. mSocket中解析参数

    [java] view plain copy
    1. try{
    2. args=readArgumentList();
    3. descriptors=mSocket.getAncillaryFileDescriptors();
    4. }catch(IOExceptionex){
    5. Log.w(TAG,"IOExceptiononcommandsocket"+ex.getMessage());
    6. closeSocket();
    7. returntrue;
    8. }

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

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

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

    总结:

  4. 在android中SystemService的启动是在Zygote进程创建好后进行的,并且由Zygote进程建立好DVM运行环境,加载ZygoteInit的main函数,最终调用Zygote的本地方法forkSystemServer,并执行linux的fork方法创建SystemServer进程。
  5. 应用程序的进程也是由Zygote创建的,在ActivityManagerService中的startProcessLocked中调用了Process.start()方法。并通过连接调用Zygote的native方法forkAndSpecialize,执行fork任务。
  6. 应用进程和服务进程位于不同的进程中,他们之间是通过IPC进行数据传递的。接下来一篇会介绍在android中的进程间通信机制:Binder

更多相关文章

  1. C语言函数的递归(上)
  2. Android圆形进度条控件-CircleSeekBar
  3. android ndk 开发之 在 框架层使用 jni
  4. Android中各种Adapter的使用方法
  5. Android系列之GreenDao数据升级和加密(三)
  6. 安卓NDK——原生开发工具包
  7. 【Android】显示网络图片代码分析
  8. Android(安卓)ListView使用BaseAdapter与ListView的优化
  9. Android网络图片加载框架的选择

随机推荐

  1. Android中Message机制的灵活应用
  2. Android:改变 Toolbar 的文字和溢出图标颜
  3. Android(安卓)GUI系统学习1:Gralloc
  4. Android获取已安装应用信息(图标,名称,版本
  5. Android(安卓)启动Activity面流程(Android
  6. Android(安卓)API 中文 (55) ―― ListAdap
  7. Android四种Activity的加载模式
  8. JavaScript 通过native.js 调用Android原
  9. [Android] 获取Android设备的唯一识别码|
  10. android 反汇编,修改,重新打包