Android启动(四)Zygote进程启动

zygote 启动

通过 init进程 这篇 我们知道 在解析init.rc时主要做了ServiceManager,zygote的启动

在 init.rc中有一句 import /init.${ro.zygote}.rc 在7.0之后 zygote 分为多个文件

执行时会根据条件执行其中一个我们看zygote32

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks

执行zygote文件

  • 可看到上面通过app_process 执行了 zygot32文件

    • app_process 一个可执行程序,是通过启动一个Android虚拟机并加载相应的Java类来启动一个进程,其实现代码在app_main.cpp文件中

    • 我们来看main函数

    • int main(int argc, char* const argv[])
      {
          //解析运行时参数。在第一个未识别的选项处停止
          bool zygote = false;
          bool startSystemServer = false;
          bool application = false;
          String8 niceName;
          String8 className;
          ++i;  // 跳过未使用的模块
          // 根据参数值判断启动zygote 或者application
          while (i < argc) {
              const char* arg = argv[i++];
              if (strcmp(arg, "--zygote") == 0) {
                  // 启动的是zygote进程
                  zygote = true;
                  niceName = ZYGOTE_NICE_NAME;
              } else if (strcmp(arg, "--start-system-server") == 0) {
                  //需要启动SystemServer
                  startSystemServer = true;
              } else if (strcmp(arg, "--application") == 0) {
                  //启动的是应用进程
                  application = true;
              } else if (strncmp(arg, "--nice-name=", 12) == 0) {
                  niceName.setTo(arg + 12);
      		} else if (strncmp(arg, "--", 2) != 0) {
                  className.setTo(arg);
                  break;
              } else {
                  --i;
                  break;
              }
          }
          // 通过AppRuntime.start(AppRuntime继承自AndroidRuntime)启动 zyogte
          //app_main.cpp在zygote启动其他进程的时候都会通过main()方法
          if (zygote) {
              runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
          } else if (className) {
              runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
          } else {
              fprintf(stderr, "Error: no class name or --zygote supplied.\n");
              app_usage();
              LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
      
    • 观察上面代码最终通过runtime.start来启动了Zygote

AndroidRuntime.start 启动zygote

  • runtime 是AppRunTime 的对象,AppRunTime 继承自AndroidRuntime,所以实际是AndroidRuntime.start启动了zygote

  • void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
    {	
        //启动虚拟机
        if (startVm(&mJavaVM, &env, zygote) != 0) {
            return;
        }
        onVmCreated(env);
        /*
         * 通过JNI关联java层,注册android功能。
         */
        if (startReg(env) < 0) {
            return;
        }
    
        /*
         * 启动虚拟机。此线程成为VM的主线程,在VM退出之前不会返回
         * slashClassName 为传进来的ZygoteInit
         * 执行zygoteInit main函数
         */
        char* slashClassName = toSlashClassName(className);
        jclass startClass = env->FindClass(slashClassName);
         //JNI 调用执行ZygoteInit的main函数 从这开始进入java代码了
        env->CallStaticVoidMethod(startClass, startMeth, strArray);
    
     }
    
  • 在AndroidRuntime的start方法中

    • 调用startVmVM()函数启动虚拟机-zygote
    • 调用startReg()函数注册 Android 的 Java 方法,其实在这里就是 JNI 方法
    • 调用CallStaticVoidMethod执行 Java 类com.android.internal.os.ZygoteInit#main()方法(Jni实现)
    • 最终执行了ZygoteInit#main()
执行ZygoteInit#main()
public static void main(String argv[]) {
    	 //1 创建zygoteService
       ZygoteServer zygoteServer = new ZygoteServer();
  		//2 注册并创建名为 zygote 的 LocalServerSocket 
        zygoteServer.registerServerSocket(socketName);
        if (!enableLazyPreload) {
           //3 首次进入 预加载资源
           preload(bootTimingsTraceLog);
        } 
  			//4 启动SystemServer 通过Zygote.forkSystemService
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
            }
    		//5 启动循环,让上面注册的LocalServerSocket接收AMS的请求
           zygoteServer.runSelectLoop(abiList);
           zygoteServer.closeServerSocket();
   }
void registerServerSocket(String socketName) {
      if (mServerSocket == null) {
          int fileDesc;
          // fullSocketname的值是ANDROID_SOCKET_zygote
          final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
          // 获取Socket名称对应的环境变量
          String env = System.getenv(fullSocketName);
          fileDesc = Integer.parseInt(env);
          // 根据环境变量创建文件描述符
          FileDescriptor fd = new FileDescriptor();
          fd.setInt$(fileDesc);
          // 根据文件描述符创建Socket
          mServerSocket = new LocalServerSocket(fd);
    }
  }
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
    //文件描述符列表
    ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
    //socket连接列表
    ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

    fds.add(mServerSocket.getFileDescriptor());
    peers.add(null);
	// 开启while循环接收请求
    while (true) {
        StructPollfd[] pollFds = new StructPollfd[fds.size()];
        for (int i = 0; i < pollFds.length; ++i) {
            pollFds[i] = new StructPollfd();
            pollFds[i].fd = fds.get(i);
            pollFds[i].events = (short) POLLIN;
        }
        try {
            Os.poll(pollFds, -1);
        } catch (ErrnoException ex) {
            throw new RuntimeException("poll failed", ex);
        }
        for (int i = pollFds.length - 1; i >= 0; --i) {
            if ((pollFds[i].revents & POLLIN) == 0) {
                 continue;
            }
            if (i == 0) {
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                boolean done = peers.get(i).runOnce(this);
                if (done) {
                    peers.remove(i);
                    fds.remove(i);
                }
            }
        }
    }
}
  • 上面我们主要关注三件事
    • 注册名为 zygote 的 LocalServerSocket 用来接收AMS请求
    • 启动SystemServer进程 后面单独说
    • runSelectLoop启动循环让上面注册的LocalServerSocket等待接收AMS的请求,在runSelectLoop
      • 开启while循环接收ActivityManagerService发送过来的请求
      • 当接收到请求之后 ZygoteConnection的runOnce函数来创建一个新的应用程序进程。并在成功创建后将这个连接从Socket连接列表peers和文件描述符列表fds中清除。
        • peers.get(i).runOnce(); peers.remove(i); fds.remove(i);

总结

  • 通过zygote文件 通知init进程需要执行app_process程序实现代码在app_main.cpp
  • app_main.cpp
    • 通过AndroidRuntime.start启动zygote
  • AndroidRuntime.start中
    • 开启虚拟机
    • 关键java代码注册android功能
    • 执行ZygoteInit.main函数
      • 注册名为 zygote 的 LocalServerSocket 用来接收AMS请求
      • 启动SystemServer进程
      • runSelectLoop启动循环让注册的LocalServerSocket 等待接收Ams的请求
  • 到此 zygote 就启动完成,runselectLoop中一直等待,使zygote进程持续运行
  • 当我们需要启动一个 应用 AMS 会通过 Socket 进程进行 IPC 通信,通知zygote进程为这个应用程序创建一个新的进程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值