Android 从 zygote 到 launcher

前言

基于 4.4 的追溯过程,因为是基于 txt 写的,所以可以复制出来再看

主题

在Android中,zygote是整个系统创建新进程的核心装置。从字面上看,zygote是受精卵的意思,它的主要工作就是进行细胞分裂。
zygote进程在内部会先启动Dalvik虚拟机,继而加载一些必要的系统资源和系统类,最后进入一种监听状态。在后续的运作中,当其他
系统模块(比如AMS)希望创建新进程时,只需向zygote进程发出请求,zygote进程监听到该请求后,会相应地“分裂”出新的进程,于是
这个新进程在初生之时,就先天具有了自己的Dalvik虚拟机以及系统资源。
系统启动伊始,zygote进程就会被 init 进程启动起来 init.rc 中启动 zygote 进程:

    app_process 用于启动 Java 程序,它将生成一个 dalvik 虚拟机运行,让 Java 代码运行于虚拟机中 
它的源码为 frameworks/base/cmds/app_process/app_main.cpp,生成的可执行文件为 Android 设备中的 
/system/bin/app_process 
    app_process 的通常用于如下:
        app_process [java-options] cmd-dir start-class-name [options] 

    其中各项功能如下:
        java-options: 传递给虚拟机的参数选项 
        cmd-dir: java 程序所在路径 
        start-class-name: java 程序的类名称 
        [options]: 传递给 app_process 的参数选项,主要包括以下几项:
            "--zygote": 是否为 zygote 进程 
            "--start-system-server": 是否为启动 system_server 的进程 
            "--application": 是否启动用程序 
            "--nice-name=": 指定进程的名称 

流程总结:

frameworks\base\cmds\app_process\app_main.cpp
///////////////////////////////////////////////////////////////////////////
// 执行程序时的参数: 
//      /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
main()
  // 先构造了一个 AppRuntime 对象,即 AppRuntime runtime;而后把进程名改成“zygote”,并利用 runtime 对象,
  // 把工作转交给 java 层的 ZygoteInit 类处理。
  AppRuntime runtime;
  // 会跳过-Xzygote,i的位置对应 /system/bin 
  int i = runtime.addVmArguments(argc, argv);
  if (zygote) 
  {
      // 这个 AppRuntime 类继承于 AndroidRuntime 类,却没有重载其 start(...) 函数,所以 main() 函数中调用
      // 的 runtime.start(...) 其实走的是 AndroidRuntime 的 start(...),而且传入了类名参数,即字符串——
      // “ com.android.internal.os.ZygoteInit ”
      // frameworks\base\core\jni\AndroidRuntime.cpp
      // 这个函数就是调用 com.android.internal.os.ZygoteInit 类的 main() 静态函数 
      runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : "");   
                      AndroidRuntime::start//(const char* className, const char* options)
                              ///////////////////////////////////////////////////////////
                              // 初始化 JNI 接口, 因为后面用到的 FindClass() 之类的类
                              jni_invocation.Init(NULL); 
                              /////////////////////////////////////////////////////////////
                              // 启动虚拟机
                              if (startVm(&mJavaVM, &env) != 0)
                                    AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
                                    {
                                        // 获得属性文件里面一此虚拟机设备的属性 
                                        property_get("dalvik.vm.checkjni", propBuf, "");
                                        。。。。
                                        // 启动 dalvik 虚拟机 
                                        JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs)
                                    }
                              
                              // 注册 Android 系统需要的 jni 函数  
                              if (startReg(env) < 0) 
                                      AndroidRuntime::startReg//(JNIEnv* env)
                                                // 注册一些重要的 jni 接口
                                                if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0)

                              // 将传入的类名字符串参数辗转传给 FindClass("com.android.internal.os.ZygoteInit")
                              char* slashClassName = toSlashClassName(className);
                              jclass startClass = env->FindClass(slashClassName);

                              ////////////////////////////////////////////////////////////////////////////
                              // 加载 ZygoteInit 类 
                              // 【这是很关键的一步,就在这一步,控制权就转移到Java层次了】
                              // 调用 com.android.internal.os.ZygoteInit 这个类的静态 main() 方法
                              // AppRuntime 的 start() 最后会加载 Java 层次的 ZygoteInit 类,并利用 JNI 技术的 
                              // CallStaticVoidMethod()调用其静态的 main() 函数
                              env->CallStaticVoidMethod(startClass, startMeth, strArray);
                                          // frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
                                          public static void main//(String argv[]) 
                                          {
                                            try{
                                                ///////////////////////////////////////////////////////////////////////
                                                //  在 init.rc 中已经创建了 
                                                // service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
                                                //     class main
                                                //     socket zygote stream 660 root system                        // 这个服务的 socket 选项表明,它需要一个名为“zygote”的“流型(stream)”socke
                                                //     onrestart write /sys/android_power/request_state wake
                                                //     onrestart write /sys/power/state on
                                                //     onrestart restart media
                                                //     onrestart restart netd
                                                //     onrestart restart surfaceflinger
                                                // 具体创建流程见 Android Init.c 分析.c 
                                                // init 进程在新 fork 出的 zygote 进程里,是如何将 socket 的文件描述符记录记录
                                                // 在“ANDROID_SOCKET_zygote”环境变量的,这里将会进行监听这个 socket  
                                                registerZygoteSocket();
                                                
                                                //////////////////////////////////////////////////////////////////////////////////
                                                // 预加载一些类,这些类记录在 frameworks/base/preloaded-classes 文本文件里
                                                preload();

                                                // 预加载一些系统资源
                                                // 基本上有两大类资源:
                                                //    1)一类和图片有关(preloaed_drawables)
                                                //    2)另一类和颜色有关(preloaded_color_state_lists)
                                                preloadResources();

                                                /////////////////////////////////////////////////////////////
                                                // 启动整个 Android 系统的系统服务
                                                // 接下来就是启动 Android 的重头戏了,此时 ZygoteInit 的 main() 函数会调用 startSystemServer(),
                                                // 该函数用于启动整个 Android 系统的系统服务。其大体做法是先 fork 一个子进程,然后在子进程中做一些
                                                // 初始化动作,继而执行 SystemServer 类的 main() 静态函数。需要注意的是,startSystemServer() 并不是
                                                // 在函数体内直接调用 Java 类的 main() 函数的,而是通过抛异常的方式,在 startSystemServer() 之外加以处理的。
                                                if (argv[1].equals("start-system-server")) {
                                                    startSystemServer();
                                                            private static boolean startSystemServer//() throws MethodAndArgsCaller, RuntimeException
                                                                          // fork 出系统服务对应的进程  
                                                                          pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities);

                                                                          // 这里在 fork 的子进程中执行的, 即 SystemServer 进程中 
                                                                          if (pid == 0)
                                                                          {
                                                                              // 对新 fork 出的系统进程,执行 handleSystemServerProcess(), 让这个新进程成为真正的系统进程(SystemServer进程)
                                                                              handleSystemServerProcess(parsedArgs);
                                                                                      // 因为当前已经不是运行在 zygote 进程里了,所以 zygote 里的那个监听 socket 就应该关闭了。这就是 closeServerSocket() 的意义
                                                                                      closeServerSocket();
                                                                                      // 此时的 remainingArgs 就是 ”com.android.server.SystemServer”
                                                                                      RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
                                                                                                  public static final void zygoteInit//(int targetSdkVersion, String[] argv) throws ZygoteInit.MethodAndArgsCaller 
                                                                                                                              // 在新fork出的系统进程里,需要重新定向系统输出流
                                                                                                                              redirectLogStreams();

                                                                                                                              // 设置新创建的应用进程的时区和键盘布局等通用信息                                                                                    
                                                                                                                              commonInit();

                                                                                                                              // 接下来调用的 nativeZygoteInit() 是个 JNI 函数,在 AndroidRuntime.cpp 文件中可以看到
                                                                                                                              // 内部会启动线程池,用于 Binder 通信 
                                                                                                                              nativeZygoteInit();

                                                                                                                              applicationInit(targetSdkVersion, argv);
                                                                                                                                  //////////////////////////////////////////////////////////////////////////////
                                                                                                                                  // 【其中的invokeStaticMain()一句最为关键,它承担向外抛出“特殊异常”的作用】
                                                                                                                                  invokeStaticMain(args.startClass, args.startArgs);
                                                                                                                                          //  抛出异常后,会跳转到下面代码的 catch (MethodAndArgsCaller caller) 继续运行,在那里调用 caller.run() 会进入下面
                                                                                                                                          // 代码的 run() 函数  
                                                                                                                                          // 【使用抛出异常启动原因】可以清函数调用栈 
                                                                                                                                          throw new ZygoteInit.MethodAndArgsCaller(m, argv);

                                                                          }
                                                ///////////////////////////////////////////////
                                                // 正常情况下子进程这一段代代码不会被执行
                                                // 而父进程因为没有抛出异常,所以会执行在这里进行死循环,进行循环监听状态

                                                //  每当 Activity Manager Service 向它发出“启动新应用进程”的命令时,它又会 fork 
                                                // 一个子进程,并在子进程里抛出一个异常,这样子进程还是会跳转到 catch 一句
                                                // Log.i(TAG, "Accepting command socket connections");
                                                runSelectLoop();
                                                        // while循环中,不断调用 selectReadable()
                                                        while (true) {
                                                              // 该函数是个native函数,对应C++层的 com_android_internal_os_ZygoteInit_selectReadable()
                                                              index = selectReadable(fdArray);
                                                              
                                                              do {
                                                                  //  主体函数就是一个 select() 负责监视若干文件描述符的变化情况,我们常见的变化情况有:读、写、异常等等
                                                                  // 最后三个参数都为 NULL,表示该 select() 操作只打算监视文件描述符的“读变化”,而且如果没有可读的文件,
                                                                  // select() 就维持阻塞状态
                                                                  err = select (nfds, &fdset, NULL, NULL, NULL);
                                                              } while (err < 0 && errno == EINTR);

                                                              
                                                              // 假设 ActivityManagerService 发来一个创建 Activity 组件请求,处理到这里就会创建一个新的应用进程
                                                              done = peers.get(index).runOnce();
                                                                                // 我们知道,当AMS需要启动一个新进程时,会调用类似下面的句子
                                                                                //    Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",  
                                                                                //                        app.processName, uid, uid, gids, debugFlags, mountExternal,  
                                                                                //                        app.info.targetSdkVersion, app.info.seinfo, null);  
                                                                                //    包括 ActivityThread 类名等重要信息的参数,最终就会通过 socket 传递给 zygote。 
                                                                                // 从 socket 中读取参数数据, 写数据的是 AMS(Activity Manager Server)
                                                                                args = readArgumentList();  

                                                                                // 内部调用 fork() 出一个子进程
                                                                                pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,  
                                                                                        parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal,   
                                                                                        parsedArgs.seInfo, parsedArgs.niceName);  
                                                                                
                                                                                if (pid == 0) { 
                                                                                        /////////////////////////////////////////////////////////////////////////////////////////
                                                                                        // 抛出异常,让子进程能跳出循环,执行自己程序的 main 函数 
                                                                                        ZygoteInit.invokeStaticMain(cloader, className, mainArgs);  
                                                                                }
                                                        }

                                            }
                                            ////////////////////////////////////////////////////////////////////////////////
                                            // 在这里捕捉子进程抛出来的异常
                                            catch (MethodAndArgsCaller caller) {
                                                  // 这里接收上面 startSystemServer() 函数内部抛出的异常,相当于从那里直接 goto 到这里,中间的程序不会执行了
                                                  // runSelectLoop() 里面也会抛出,如 ActivityManagerService 请求 zygote 创建 Actiivty 组件时, 也会 fork 个子进程抛异常 

                                                  //  有一点需要说明一下,fork 出的 SystemServer 进程在跳转到 catch 语句后,会执行 SystemServer 类
                                                  // 的 main() 函数,而其他情况下,fork 出的应用进程在跳转的 catch 语句后,则会执行 ActivityThread 类
                                                  // 的 main() 函数。这个 ActivityThread 对于应用程序而言非常重要 【使用抛出异常启动原因】可以清函数调用栈 
                                                  caller.run();// 为什么会执行到 main ? 【原因在抛出异常位置有说,经过了中间类】因为使用的是多线程机制, run() 是找多线程运行的意思,而不是执行 run() 函数
                                                          // 在异常处理中会调用 run() 就是这里的,因为在这里实现的 Runnable 多线程接口
                                                          public static class MethodAndArgsCaller extends Exception implements Runnable// Runnable 是多线程的意思吧
                                            }                                 // 在下面的异常捕获中运行的 caller.run() 会运行到这里
                                                                              public void run() {
                                                                                    ////////////////////////////////////////////////////////////////////////////////////////////////////////
                                                                                    // 在这里执行要执行的类的 main() 函数,为什么是 main() 函数,那就上面抛出时设置的 
                                                                                    mMethod.invoke(null, new Object[] { mArgs });
                                                                                            ///////////////////////////////////////////////////////////////////////////////
                                                                                            // 这里执行的是 SystemServer 类 的 main() 函数
                                                                                            public static void main//(String[] args) 
                                                                                            {
                                                                                                // 调用 loadLibrary() 加载  HAL 库,位于文件 onload.cpp 
                                                                                                // 会调用 onload.cpp 的 JNI_OnLoad(), 注册各个硬件访问子服务
                                                                                                System.loadLibrary("android_servers");
                                                                                                                                                                          
                                                                                                // 调用 ServerThread.initAndLoop(), 注册系统的关键服务,如 ActivityManagerService,PackageManagerService 等等
                                                                                                ServerThread thr = new ServerThread();
                                                                                                thr.initAndLoop();
                                                                                                        ///////////////////////////////////////////
                                                                                                        // 创建主线程消息队列
                                                                                                        Looper.prepareMainLooper();
                                                                                                        
                                                                                                        power = new PowerManagerService();
                                                                                                        ServiceManager.addService(Context.POWER_SERVICE, power);

                                                                                                        // 会等待 PackageManagerService 启动后注册服务 ActivityManagerService
                                                                                                        Slog.i(TAG, "Activity Manager");
                                                                                                        context = ActivityManagerService.main(factoryTest);
                                                                                                        

                                                                                                        Slog.i(TAG, "Package Manager");
                                                                                                        pm = PackageManagerService.main(context, installer,
                                                                                                                factoryTest != SystemServer.FACTORY_TEST_OFF,
                                                                                                                onlyCore);
                                                                                                        
                                                                                                        // 注册服务 ActivityManagerService
                                                                                                        ActivityManagerService.setSystemProcess();

                                                                                                        Slog.i(TAG, "User Service");
                                                                                                        ServiceManager.addService(Context.USER_SERVICE,
                                                                                                                UserManagerService.getInstance());
                                                                                                                
                                                                                                        Slog.i(TAG, "System Content Providers");
                                                                                                        ActivityManagerService.installSystemProviders();
                                                                                                        
                                                                                                        Slog.i(TAG, "Window Manager");
                                                                                                        wm = WindowManagerService.main(context, power, display, inputManager,
                                                                                                                wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
                                                                                                                !firstBoot, onlyCore);
                                                                                                        ServiceManager.addService(Context.WINDOW_SERVICE, wm);

                                                                                                        ////////////////////////////////////////////////////////////////////////////////
                                                                                                        // 从这里启动 launcher 的 Activity 组件 
                                                                                                        ////////////////////////////////////////////////////////////////////////////////
                                                                                                        ActivityManagerService.self().systemReady(new Runnable() {。。。});
                                                                                                                    ActivityManagerService::systemReady()
                                                                                                                            mStackSupervisor.resumeTopActivitiesLocked();
                                                                                                                                      ActivityStack::resumeTopActivityLocked()
                                                                                                                                              ////////////////////////////////////////////////////////////////////////
                                                                                                                                              //  这里调用函数 topRunningActivityLocked 返回的是当前系统 Activity 堆栈
                                                                                                                                              // 最顶端的 Activity,由于此时还没有 Activity 被启动过,因此,返回值为 null,
                                                                                                                                              // 即 next 变量的值为 null,于是就调用 mService.startHomeActivityLocked 函数
                                                                                                                                              if (next == null) {
                                                                                                                                                  // There are no more activities!  Let's just start up the
                                                                                                                                                  // Launcher...
                                                                                                                                                  ActivityOptions.abort(options);

                                                                                                                                                  /// M: Power off alarm feature:
                                                                                                                                                  /// If mAlarmBoot is TRUE, that means this is alarm boot-up
                                                                                                                                                  /// We will skip to resume home activity until the Alarm activity is destroyed. @{
                                                                                                                                                  if (PowerOffAlarmUtility.isAlarmBoot()) {
                                                                                                                                                      Slog.v(TAG, "Skip to resume home activity!!");
                                                                                                                                                      return false;
                                                                                                                                                  }
                                                                                                                                                  /// @}

                                                                                                                                                  if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
                                                                                                                                                  if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();

                                                                                                                                                  return mStackSupervisor.resumeHomeActivity(prev);
                                                                                                                                                            ActivityStackSupervisor::resumeHomeActivity()
                                                                                                                                                                    return mService.startHomeActivityLocked(mCurrentUser);
                                                                                                                                                                              ActivityManagerService::startHomeActivityLocked()
                                                                                                                                                                                              Intent intent = getHomeIntent();
                                                                                                                                                                                                                    Intent getHomeIntent() {
                                                                                                                                                                                                                            Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
                                                                                                                                                                                                                            intent.setComponent(mTopComponent);
                                                                                                                                                                                                                            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
                                                                                                                                                                                                                                /////////////////////////////////////////////////////////////////////
                                                                                                                                                                                                                                // 这里就是 Launcher 组件的属性
                                                                                                                                                                                                                                intent.addCategory(Intent.CATEGORY_HOME);
                                                                                                                                                                                                                            }
                                                                                                                                                                                                                            return intent;
                                                                                                                                                                                                                        }
                                                                                                                                                                                              // 通过 resolveActivityInfo() 向 PackageManagerService 查询到带 CATEGORY_HOME 属性的 Launcher 
                                                                                                                                                                                              // 程序信息
                                                                                                                                                                                              ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
                                                                                                                                                                                              // 然后启动他 
                                                                                                                                                                                              mStackSupervisor.startHomeActivity(intent, aInfo);  
                                                                                                                                                                                                          ActivityStackSupervisor::startHomeActivity()
                                                                                                                                                                                                                            // 移动到栈顶
                                                                                                                                                                                                                            moveHomeToTop();
                                                                                                                                                                                                                            ///////////////////////////////////////////////////////////////////////////////////////////////////
                                                                                                                                                                                                                            // 调用 ActivityManagerService::startActivityLocked() 启动 Launcher 程序 
                                                                                                                                                                                                                            // 【startActivityLoked() 详见 Android 源码情景分析:16.2 应用程序的显示过程】                                                               
                                                                                                                                                                                                                            startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0, null, false, null);
                                                                                                                                              }             

                                                                                                        // 循环等待消息队列
                                                                                                        Looper.loop();
                                                                                            }

                                                                              }

                                          }



  }

猜你喜欢

转载自blog.csdn.net/wangjun7121/article/details/88135935