Android4.0 Zygote和启动过程

 

    在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。在系统启动脚本system/core/rootdir/init.rc文件中。

一、在init.rc脚本文件中:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 666
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
  onrestart restart netd

service zygote  init进程创建一个名为"zygote"的进程

/system/bin/app_process      zygote进程要执行的程序

-Xzygote  传递给VM的选项,-Xzygote 选项用来区分要在虚拟机中运行的类是Zygote,还是在Zygote中运行的其他Android应用程序。

/system/bin 运行目录参数/system/bin 保存到 parentDir 变量中。 

--zygote  用来指定加载到虚拟机中类的名称,表示加载com.android.internel.os.ZygoteInit类。

--start-system-server  作为选项传递给生成的类,用于启动运行System server

socket zygote stream 666  套接字的名称,种类,访问权限

Zygote进程要执行的程序便是system/bin/app_process了,在frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main

int main(int argc, const char* const argv[])
{
    // These are global variables in ProcessState.cpp
    mArgC = argc;
    mArgV = argv;

    mArgLen = 0;
    for (int i=0; i<argc; i++) {
        mArgLen += strlen(argv[i]) + 1;
    }
    mArgLen--;

    AppRuntime runtime;
    const char* argv0 = argv[0];

    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;

    // Everything up to '--' or first non '-' arg goes to the vm

    int i = runtime.addVmArguments(argc, argv);//

    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    const char* parentDir = NULL;
    const char* niceName = NULL;
    const char* className = NULL;
    while (i < argc) {
        const char* arg = argv[i++];//运行目录参数/system/bin 保存到 parentDir 变量中 
        if (!parentDir) {
            parentDir = arg;
        } else if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = "zygote";
        } 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 = arg + 12;
        } else {
            className = arg;
            break;
        }
    }

    if (niceName && *niceName) {
        setArgv0(argv0, niceName);
        set_process_name(niceName);
    }

    runtime.mParentDir = parentDir;

    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "");
//调用AppRuntime的start()成员函数,生成并初始化虚拟机,然后将ZygoteInit()类加载到虚拟机中,执行其中的main()方法。
    } else if (className) {
        // Remainder of args get passed to startup class main()
        runtime.mClassName = className;
        runtime.mArgC = argc - i;
        runtime.mArgV = argv + i;
        runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool");
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        return 10;
    }
}

此函数主要工作:分析传递给虚拟机的参数,并保存到AppRuntime类的对象中,然后加载对象,调用对象的main()方法。

 

二、进入到AndroidRuntime.cpp 中start()函数中

void AndroidRuntime::start(const char* className, const char* options)
{
    LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
            className != NULL ? className : "(unknown)");

    blockSigpipe();

    /*
     * 'startSystemServer == true' means runtime is obsolete and not run from
     * init.rc anymore, so we print out the boot start event here.
     */
    if (strcmp(options, "start-system-server") == 0) {
        /* track our progress through the boot sequence */
        const int LOG_BOOT_PROGRESS_START = 3000;
        LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
                       ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
    }

    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }

    //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
    //LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);

    /* start the virtual machine *///创建java虚拟机
    JNIEnv* env;
    if (startVm(&mJavaVM, &env) != 0) {//mJavaVM 生成的JavaVM类的接口指针,env  JNIEnv类的接口指针,方便访问虚拟机
        return; 
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {//注册虚拟机要使用的JNI函数,以后运行在虚拟机中的JAVA类就可以调用本地函数。
        LOGE("Unable to register all android natives\n");
        return;
    }

    /*
     * We want to call main() with a String array with arguments in it.
     * At present we have two arguments, the class name and an option string.
     * Create an array to hold them.
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;
    jstring optionsStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(2, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);
    optionsStr = env->NewStringUTF(options);
    env->SetObjectArrayElement(strArray, 1, optionsStr);

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    char* slashClassName = toSlashClassName(className);//将类名称中的 "."替换成"/",
    jclass startClass = env->FindClass(slashClassName);//在由类名称解析出来的路径下查找指定的类,若存在,测加载。
    if (startClass == NULL) {
        LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");//在类中查找形式参数为String数组且返回值为void的main()静态方法。
        if (startMeth == NULL) {
            LOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);//找到次方法,调用此方法,此时程序的执行转到虚拟机中运行的java应用程序上。
            //进入到ZygoteInit.java--ZygoteInit::main()方法中
			
... ...
        }
    }
... ...
}


三、进入到ZygoteInit.java--ZygoteInit::main()方法中

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

            registerZygoteSocket();//1、绑定套接字, 接受新android应用程序运行请求
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preload();//2、加载 android application framework 使用的类和资源 ,
            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("start-system-server")) {
                startSystemServer();//3、运行systemserver
            } else if (!argv[1].equals("")) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

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

            if (ZYGOTE_FORK_MODE) {
                runForkMode();
            } else {
                runSelectLoopMode();//4、处理新android应用程序运行请求
            }

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


首先分析第一点:registerZygoteSocket();//1、绑定套接字, 接受新android应用程序运行请求

    private static void registerZygoteSocket() {
        if (sServerSocket == null) {
            int fileDesc;
            try {
                String env = System.getenv(ANDROID_SOCKET_ENV);//获取套接字的文件描述符。它记录在ANDROID_SOCKET_zygote环境变量中。
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                throw new RuntimeException(
                        ANDROID_SOCKET_ENV + " unset or invalid", ex);
            }

            try {
                sServerSocket = new LocalServerSocket(
                        createFileDescriptor(fileDesc));//使用套接字文件描述符创建LocalServerSocket的实例,将其与/dev/socket/zygote绑定在一起
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
  }

第二点:加载 android application framework 使用的类和资源

  static void preload() {
        preloadClasses();
        preloadResources();
  }
  
    private static void preloadClasses() {
        final VMRuntime runtime = VMRuntime.getRuntime();
        InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(
                PRELOADED_CLASSES);//获取一个输入流,以便读取proloaded-classes文件中的类 ,framework/base/preloafed-classes文件。
... ... 
            try {
                BufferedReader br
                    = new BufferedReader(new InputStreamReader(is), 256);//创建BufferedReader对象,并读取文件中的内容。
... ...
                    line = line.trim();//忽略文件中的注释和空行,读取下一行
                    if (line.startsWith("#") || line.equals("")) {
                        continue;
                    }
... ...
  Class.forName(line);//将读取到得类动态的加载到内存中
  ... ... 
}

第三点:运行systemserver,在ZygoteInit.java中startSystemServer()方法中


Android4.0 Zygote和启动过程_第1张图片

  private static boolean startSystemServer()
              throws MethodAndArgsCaller, RuntimeException {
          /* 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,1018,3001,3002,3003,3006,3007",
              "--capabilities=130104352,130104352",
              "--runtime-init",
              "--nice-name=system_server",
              "com.android.server.SystemServer",//用于指定systemserver类
          };
  ... ...
              pid = Zygote.forkSystemServer(
                      parsedArgs.uid, parsedArgs.gid,
                      parsedArgs.gids,
                      parsedArgs.debugFlags,
                      null,
                      parsedArgs.permittedCapabilities,
                      parsedArgs.effectiveCapabilities);//创建新进程,并运行systemserver
  ... ...
          /* For child process */
          if (pid == 0) {
              handleSystemServerProcess(parsedArgs);//在生成的systemserver进程中运行com.android.server.SystemServer类的main()方法
          }
  ... ...
}

进入handleSystemServerProcess()中

    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

... ...
     RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
... ...
  }

进入RuntimeInit.java zygoteinit方法中

      public static final void zygoteInit(int targetSdkVersion, String[] argv)
              throws ZygoteInit.MethodAndArgsCaller {
          if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
  
          redirectLogStreams();
  
          commonInit();
          zygoteInitNative();//1、native层初始化
  
          applicationInit(targetSdkVersion, argv);
      }

在进入applicationInit()中

      private static void applicationInit(int targetSdkVersion, String[] argv)
              throws ZygoteInit.MethodAndArgsCaller {
  ... ...
          invokeStaticMain(args.startClass, args.startArgs);
  //2、调用startclass,也就是com.android.server.SystemServer类的main()函数
      }

分析上面两点:

1native层初始化  zygoteInitNative()

public static final native void zygoteInitNative();他是一个本地函数,经过JNI调用AndroidRuntime.cpp中的

static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}


gCurRuntime是指什么?

gCurRuntime

在app_main.cpp   main()函数中

int main(int argc, const char* const argv[])
{
... 
AppRuntime runtime;
... ...
}

看其定义

class AppRuntime : public AndroidRuntime

继承AndroidRuntime

static AndroidRuntime* gCurRuntime = NULL; //为全局变量

AndroidRuntime.cpp中

AndroidRuntime::AndroidRuntime()
{
    SkGraphics::Init();
... ...
    gCurRuntime = this;  // gCurRuntime 被设置为AndroidRuntime对象自己
}

故:此时启动App_main.cpp中onZygoteInit()函数

    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        LOGV("App process: starting thread pool.\n");
        proc->startThreadPool();//启动一个线程,用于binder通信
  }

2、invokeStaticMain(args.startClass, args.startArgs)

调用startclass,也就是com.android.server.SystemServer类的main()函数

      private static void invokeStaticMain(String className, String[] argv)
              throws ZygoteInit.MethodAndArgsCaller {
... ...
              m = cl.getMethod("main", new Class[] { String[].class });
  //找到com.android.server.SystemServer类的main()函数

... ...
          throw new ZygoteInit.MethodAndArgsCaller(m, argv);//抛出一个异常
      }

将在ZygoteInitmain函数中截获到,

ZygoteInit.java的main()中

  public static void main(String argv[]) {
  ... ...
          try {
  ... ... 
              if (argv[1].equals("start-system-server")) {
                  startSystemServer();//运行systemserver   在此中抛出一个异常
              } else if (!argv[1].equals("")) {
                  throw new RuntimeException(argv[0] + USAGE_STRING);
              }
          } catch (MethodAndArgsCaller caller) {
              caller.run();       
   ... ...
          }

将进入MethodAndArgsCaller run函数

        public void run() {
            try {
//mMethod为com.android.server.SystemServer的main()函数
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
... ...
        }

现在进入到SystemServer.java的main

    public static void main(String[] args) {
... ...
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

        System.loadLibrary("android_servers");//加载android_servers本地库文件
        init1(args);
    }


进入init1()为本地方法,将进入

native public static void init1(String[] args);

com_android_server_SystemServer.cpp中的

  static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
  {
      system_init();
  }

extern "C" int system_init();将调用system_init.cpp中的system_init(0函数

  extern "C" status_t system_init(){
  ... ...
      property_get("system_init.startsurfaceflinger", propBuf, "1");
      if (strcmp(propBuf, "1") == 0) {
          // Start the SurfaceFlinger
          SurfaceFlinger::instantiate();//注册本地服务
      }
  ......
      jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");//调用init2()方法
  
  ... ...
  }

init2()方法

      public static final void init2() {
          Slog.i(TAG, "Entered the Android system server!");
          Thread thr = new ServerThread();
          thr.setName("android.server.ServerThread");
          thr.start();/创建一个线程android.server.ServerThread,并启动它
      }


第四点:处理新android应用程序运行请求 runSelectLoopMode()

    private static void runSelectLoopMode() throws MethodAndArgsCaller {
... ...
fds.add(sServerSocket.getFileDescriptor());//将套接字的描述符添加到描述符数组中
......
 boolean done;
                done = peers.get(index).runOnce();//处理新连接的输入输出套接字,并生成新的android应用程序。
... ...
}


进入zygoteconnection.java中的runonce()

  boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
     .... ...
  args = readArgumentList();//读取请求信息,请求信息包含创建新进程的参数选项
  ... ...
  parsedArgs = new Arguments(args);//分析请求信息中的字符数组,为运行进程设置好各个选项
  ... ...
 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
           parsedArgs.gids, parsedArgs.debugFlags, rlimits);//创建新进程
              if (pid == 0) {
                  // in child
                  IoUtils.closeQuietly(serverPipeFd);//
                  serverPipeFd = null;
                  handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);//加载新进程所需的类,并调用类的main()方法。启动新的应用程序。子进程处理
  
                  // should never get here, the child is expected to either
                  // throw ZygoteInit.MethodAndArgsCaller or exec().
                  return true;
              } else {
                  // in parent...pid of < 0 means failure
                  IoUtils.closeQuietly(childPipeFd);
                  childPipeFd = null;
                  return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);//zygote进程
              }
  }


进入到新进程创建的子进程中的处理 handleChildProc()

  ZygoteConnection.java
      private void handleChildProc(Arguments parsedArgs,
              FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
              throws ZygoteInit.MethodAndArgsCaller {
  
  ... ...
                  RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
                          parsedArgs.remainingArgs);
  ... ...
  }


 

在进入到RuntimeInit.java中的zygoteinit()方法中最终调用了

invokeStaticMain(args.startClass, args.startArgs);函数,前面已经分析。

                                                                                                                android  启动过程

AndroidLinux系统启动有4个步骤;

(1) init进程启动

(2) Native服务启动

(3) System ServerAndroid服务启动

(4) Home启动

Android4.0 Zygote和启动过程_第2张图片
 

SystemServer组件接下来就要通过ActivityManagerService来启动Home应用程序Launcher了,Launcher在启动的时候便会通过PackageManagerServic把系统中已经安装好的应用程序以快捷图标的形式展示在桌面上。

第一步:在上面,讲到了启动systemserver的过程

SystemServer.java的main函数

  public static void main(String[] args) {
  ... ...
        System.loadLibrary("android_servers");
          init1(args);
      }

启动init1()函数,

native public static void init1(String[] args);

Init1()是一个本地函数,将会进入到

static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
    system_init();
}

调用extern "C" int system_init();

会进入到System_init.cpp中的system_init中

extern "C" status_t system_init()
{
... ...
    jclass clazz = env->FindClass("com/android/server/SystemServer");
    if (clazz == NULL) {
        return UNKNOWN_ERROR;
    }
  jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
  ... ...
}

初始化一些服务后,会调用com/android/server/SystemServer类中的init2()方法

Systemserver.java函数init2()

    public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();//创建了一个ServerThread线程
        thr.setName("android.server.ServerThread");
        thr.start();
  }

许多android framework服务都是在这个线程中注册的,可以查看其run方法。

如:ServiceManagerActivityManagerServicePackageManagerService等。

第二步:

run中将启动ActivityManagerService服务,

public void run() {
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
            SystemClock.uptimeMillis());

        Looper.prepare();
... ...
            Slog.i(TAG, "Activity Manager");
            context = ActivityManagerService.main(factoryTest);//1、
... ...
            ActivityManagerService.setSystemProcess();//2、

            mContentResolver = context.getContentResolver();
... ...
        ActivityManagerService.self().systemReady(new Runnable() {//3、
... ...
 	}
}

在上面的run方法中

1、在main()方法中通过AThread线程对象来内部创建了一个ActivityManagerService实例,最后将其保存到成员变量mSelf 中,然后初始化其它成员变量。

2

 public static void setSystemProcess() {
        try {
            ActivityManagerService m = mSelf;
            //将ActivityManagerService注册到server manager中区,可以通过ServiceManager.getService接口来访问这个全局唯一的ActivityManagerService实例。
            ServiceManager.addService("activity", m);
            ServiceManager.addService("meminfo", new MemBinder(m));
            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(m));
            }
            ServiceManager.addService("permission", new PermissionController(m));

            ApplicationInfo info =
                mSelf.mContext.getPackageManager().getApplicationInfo(
                        "android", STOCK_PM_FLAGS);
            mSystemThread.installSystemApplicationInfo(info);
//把在应用程序框架层下面的android包加载进来
... ...
}

3、最后调用systemReady方法

在ActivityManagerServcie.java

    public void systemReady(final Runnable goingCallback) {

        synchronized(this) {

... ...

            mMainStack.resumeTopActivityLocked(null);//启动Home应用程序

... ...

        }

}

第三步:

1、将会进入到ActivityStack.java   resumeTopActivityLocked()中

final boolean resumeTopActivityLocked(ActivityRecord prev) {

ActivityRecord next = topRunningActivityLocked(null);//返回的是当前系统Activity堆栈最顶端的Activity,此时还没有activity启动,故为null

  ... ...
        if (next == null) {
            // There are no more activities!  Let's just start up the
            // Launcher...
            if (mMainStack) {
                return mService.startHomeActivityLocked();
            }
        }
... ...
}

2、进入到ActivityManagerService.java中的startHomeActivityLocked()

  boolean startHomeActivityLocked() {
        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
                && mTopAction == null) {
            return false;
        }
        Intent intent = new Intent(
            mTopAction,
            mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        ActivityInfo aInfo =
            intent.resolveActivityInfo(mContext.getPackageManager(),
                    STOCK_PM_FLAGS);//向PackageManagerService查询Category类型为HOME的Activity。(AndroidManifest.xml中)
        if (aInfo != null) {
            intent.setComponent(new ComponentName(
                    aInfo.applicationInfo.packageName, aInfo.name));
            // Don't do this if the home app is currently being
            // instrumented.
            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                    aInfo.applicationInfo.uid);//第一次启动这个Activity,故app为null。
            if (app == null || app.instrumentationClass == null) {
                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
                        null, null, 0, 0, 0, false, false, null);//调用此函数启动这个Activity。
            }
        }      
        return true;
    }

第四步、

调用此startActivityLocked函数后,就会启动com.android.launcher2.Launcher,然后调用它的Oncreate()方法。

 

你可能感兴趣的:(Android4.0 Zygote和启动过程)