美文网首页
Android启动流程

Android启动流程

作者: zhllp | 来源:发表于2019-02-27 19:56 被阅读0次

    进程概况

    init 进程
        
        zygote进程
        
            system_server进程
    

    init进程

    init进程是Linux第一号进程(pid=1),android系统对于init进程进行了定制,主要是为了解析init.rc
    然后由init进程启动一个个的service,如:zygote,servicemanager,logd,surfaceflinger等等

    init.rc 启动脚本,init进程主要是解析配置的命令
    这里为了分析启动,只截取了zygote相应的脚本命令:

    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
        class main  #class是一个option,指定zygote服务的类型是main
        socket zygote stream 660 root system #socket关键字表示一个option。创建一个名为dev/socket/zygote,类型为stream,权限660的socket。
        onrestart write /sys/android_power/request_state wake #onrestart是一个option,说明在zygote重启时需要执行的command
        onrestart write /sys/power/state on
        onrestart restart media
        onrestart restart netd
    
    

    其中 --zygote , --start-system-server 对后面的流程很重要

    app_main.cpp

    从app_main开始

    int main(int argc, char* const argv[])
    {
        if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
            // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return
            // EINVAL. Don't die on such kernels.
            if (errno != EINVAL) {
                LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
                return 12;
            }
        }
        
        // runtime对象
        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
        // Process command line arguments
        // ignore argv[0]
        argc--;
        argv++;
    
        // Everything up to '--' or first non '-' arg goes to the vm.
        //
        // The first argument after the VM args is the "parent dir", which
        // is currently unused.
        //
        // After the parent dir, we expect one or more the following internal
        // arguments :
        //
        // --zygote : Start in zygote mode
        // --start-system-server : Start the system server.
        // --application : Start in application (stand alone, non zygote) mode.
        // --nice-name : The nice name for this process.
        //
        // For non zygote starts, these arguments will be followed by
        // the main class name. All remaining arguments are passed to
        // the main method of this class.
        //
        // For zygote starts, all remaining arguments are passed to the zygote.
        // main function.
        //
        // Note that we must copy argument string values since we will rewrite the
        // entire argument block when we apply the nice name to argv0.
    
        int i;
        for (i = 0; i < argc; i++) {
            if (argv[i][0] != '-') {
                break;
            }
            if (argv[i][1] == '-' && argv[i][2] == 0) {
                ++i; // Skip --.
                break;
            }
            runtime.addOption(strdup(argv[i]));
        }
    
        // Parse runtime arguments.  Stop at first unrecognized option.
        bool zygote = false;
        bool startSystemServer = false;
        bool application = false;
        String8 niceName;
        String8 className;
    
        ++i;  // Skip unused "parent dir" argument.
        while (i < argc) {
            const char* arg = argv[i++];
            if (strcmp(arg, "--zygote") == 0) {
                zygote = true;
                niceName = ZYGOTE_NICE_NAME;
            } 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.setTo(arg + 12);
            } else if (strncmp(arg, "--", 2) != 0) {
                className.setTo(arg);
                break;
            } else {
                --i;
                break;
            }
        }
    
        Vector<String8> args;
        if (!className.isEmpty()) {
            // We're not in zygote mode, the only argument we need to pass
            // to RuntimeInit is the application argument.
            //
            // The Remainder of args get passed to startup class main(). Make
            // copies of them before we overwrite them with the process name.
            args.add(application ? String8("application") : String8("tool"));
            runtime.setClassNameAndArgs(className, argc - i, argv + i);
        } else {
            // We're in zygote mode.
            maybeCreateDalvikCache();
    
            if (startSystemServer) {
                args.add(String8("start-system-server"));
            }
    
            char prop[PROP_VALUE_MAX];
            if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
                LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
                    ABI_LIST_PROPERTY);
                return 11;
            }
    
            String8 abiFlag("--abi-list=");
            abiFlag.append(prop);
            args.add(abiFlag);
    
            // In zygote mode, pass all remaining arguments to the zygote
            // main() method.
            for (; i < argc; ++i) {
                args.add(String8(argv[i]));
            }
        }
    
        if (!niceName.isEmpty()) {
            runtime.setArgv0(niceName.string());
            set_process_name(niceName.string());
        }
    
        //此前分析了init.rc的命令,可以看到zygote为true
        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.");
            return 10;
        }
    }
    
    

    需要注意接下来的这句

        // runtime对象
        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    
    

    通过zygote启动的布尔值将会是1,将进入:

     runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    

    runtime对象是个什么鬼,start方法又会做什么事?带着这个疑问进行

    /**
    * AppRuntime对象继承了AndroidRuntime
    */
    class AppRuntime : public AndroidRuntime
    {
        ...
        ...    
    }
    
    

    接下来看AndroidRuntime的start()
    屏蔽掉干扰的代码信息,只截取关键信息

    void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
    {
        ...
        ...
        //开启虚拟机
        if (startVm(&mJavaVM, &env, zygote) != 0) {
            return;
        }
        onVmCreated(env);
    
        /*
         * Register android functions.
         */
         //注册android的jni方法
        if (startReg(env) < 0) {
            ALOGE("Unable to register all android natives\n");
            return;
        }
        
        ...
        ...
         //前面分析 className为“com.android.internal.os.ZygoteInit”
         //此处将java全局类名分割符"."改为"/",符合JNI规则
         //所以此处的splashClassName最终为:"com/android/internal/os/ZygoteInit"
        char* slashClassName = toSlashClassName(className);
        jclass startClass = env->FindClass(slashClassName);
        
        //startClass不为空
        if (startClass == NULL) {
            ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
            /* keep going */
        } else {
            //将调用ZygoteInit的main方法
            jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
                "([Ljava/lang/String;)V");
            if (startMeth == NULL) {
                ALOGE("JavaVM unable to find main() in '%s'\n", className);
                /* keep going */
            } else {
                env->CallStaticVoidMethod(startClass, startMeth, strArray);
            
            }
        free(slashClassName);
    
        ALOGD("Shutting down VM\n");
        if (mJavaVM->DetachCurrentThread() != JNI_OK)
            ALOGW("Warning: unable to detach main thread\n");
        if (mJavaVM->DestroyJavaVM() != 0)
            ALOGW("Warning: VM did not shut down cleanly\n");
    }
    
    

    startVm:经过一系列的参数,最终通过JNI_CreateJavaVM创建虚拟机
    而创建的是ART还是Dalvik都是这个方法里面判断,此处不分析这个具体逻辑

    int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
    {
          /*
         * Initialize the VM.
         *
         * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
         * If this call succeeds, the VM is ready, and we can start issuing
         * JNI calls.
         */
        if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
            ALOGE("JNI_CreateJavaVM failed\n");
            return -1;
        }
    
        return 0;
    }
    

    再来看看startReg这个方法:

    /*
     * Register android native functions with the VM.
     */
    /*static*/ int AndroidRuntime::startReg(JNIEnv* env)
    {
        /*
         * This hook causes all future threads created in this process to be
         * attached to the JavaVM.  (This needs to go away in favor of JNI
         * Attach calls.)
         */
        androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
    
    
        if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
            env->PopLocalFrame(NULL);
            return -1;
        }
    
    
        return 0;
    }
    
    

    a. androidSetCreateThreadFunc:注释说的很清楚,这个钩子函数将会导致接下来这个进程创建的线程都被attach

    到Java虚拟机中

    b. register_jni_procs: 其中gRegJNI是一个RegJNIRec结构体的数组,里面注册jni的方法,并且将jni方法与native方法一一对应

    最后再看这段代码

         jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
                "([Ljava/lang/String;)V");
            if (startMeth == NULL) {
                ALOGE("JavaVM unable to find main() in '%s'\n", className);
                /* keep going */
            } else {
                env->CallStaticVoidMethod(startClass, startMeth, strArray);
    
            }
            
    
    

    startClass为ZygoteInit,最终会调到ZygoteInit的main方法

    ZygoteInit::main()

        public static void main(String argv[]) {
        
            //创建LocalSocketServer,由此我们知道进程与zygote进行IPC通信的方式是socket
            ZygoteServer zygoteServer = new ZygoteServer();
    
            final Runnable caller;
            try {
     
                boolean startSystemServer = false;
                String socketName = "zygote";
                String abiList = null;
                boolean enableLazyPreload = false;
                for (int i = 1; i < argv.length; i++) {
                    if ("start-system-server".equals(argv[i])) {
                        startSystemServer = true;
                    } else if ("--enable-lazy-preload".equals(argv[i])) {
                        enableLazyPreload = true;
                    } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                        abiList = argv[i].substring(ABI_LIST_ARG.length());
                    } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                        socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                    } else {
                        throw new RuntimeException("Unknown command line argument: " + argv[i]);
                    }
                }
    
                if (abiList == null) {
                    throw new RuntimeException("No ABI list supplied.");
                }
    
                //zygote的socketName是“socket”
                zygoteServer.registerServerSocket(socketName);
    
                 ...
                 ...
    
    
                if (startSystemServer) {
                        
                        //通过前面的分析将会跑到这里,看名字就可以知道fork一个进程
                    Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
    
                    // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                    // child (system_server) process.
                    if (r != null) {
                        r.run();
                        return;
                    }
                }
    
                // The select loop returns early in the child process after a fork and
                // loops forever in the zygote.
                caller = zygoteServer.runSelectLoop(abiList);
            } catch (Throwable ex) {
                Log.e(TAG, "System zygote died with exception", ex);
                throw ex;
            } finally {
                zygoteServer.closeServerSocket();
            }
    
            // We're in the child process and have exited the select loop. Proceed to execute           the
            // command.
            if (caller != null) {
                caller.run();
            }
        }
    
    

    ZygoteInit:: forkSystemServer

        private static Runnable forkSystemServer(String abiList, String socketName,
                ZygoteServer zygoteServer) {
      
            ...
            
            /* Hardcoded command line to start the system server */
            //留意最后一个参数:com.android.server.SystemServer
            String args[] = {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "com.android.server.SystemServer",
            };
            
            
            ZygoteConnection.Arguments parsedArgs = null;
    
            int pid;
    
            try {
                parsedArgs = new ZygoteConnection.Arguments(args);
                ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
                ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
    
                //通过Linux的系统调用fork出system server进程,没啥好讲的
                pid = Zygote.forkSystemServer(
                        parsedArgs.uid, parsedArgs.gid,
                        parsedArgs.gids,
                        parsedArgs.debugFlags,
                        null,
                        parsedArgs.permittedCapabilities,
                        parsedArgs.effectiveCapabilities);
            } catch (IllegalArgumentException ex) {
                throw new RuntimeException(ex);
            }
    
            /* For child process */
            if (pid == 0) {
                    //此时fork出system_server进程,将在system_server进程中处理后续工作
                zygoteServer.closeServerSocket();
                return handleSystemServerProcess(parsedArgs);
            }
            //当前在Zygote进程时,会返回null
            return null;
        }
        
    

    此时返回Zygote::main()方法最后一部分:

                 // The select loop returns early in the child process after a fork and
                // loops forever in the zygote.
                caller = zygoteServer.runSelectLoop(abiList);
    
            // We're in the child process and have exited the select loop. Proceed to execute           the
            // command.
            if (caller != null) {
                caller.run();
            }
    
    
        Runnable runSelectLoop(String abiList) {
            ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
            ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
    
            fds.add(mServerSocket.getFileDescriptor());
            peers.add(null);
    
            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 {
                        try {
                            ZygoteConnection connection = peers.get(i);
                            final Runnable command = connection.processOneCommand(this);
    
                            if (mIsForkChild) {
                                // We're in the child. We should always have a command to run at this
                                // stage if processOneCommand hasn't called "exec".
                                if (command == null) {
                                    throw new IllegalStateException("command == null");
                                }
                                return command;
                            } else {
                                // We're in the server - we should never have any commands to run.
                                if (command != null) {
                                    throw new IllegalStateException("command != null");
                                }
    
                                // We don't know whether the remote side of the socket was closed or
                                // not until we attempt to read from it from processOneCommand. This shows up as
                                // a regular POLLIN event in our regular processing loop.
                                if (connection.isClosedByPeer()) {
                                    connection.closeSocket();
                                    peers.remove(i);
                                    fds.remove(i);
                                }
                            }
                        } catch (Exception e) {
                            if (!mIsForkChild) {
                                ZygoteConnection conn = peers.remove(i);
                                conn.closeSocket();
    
                                fds.remove(i);
                            } else {
                                throw e;
                            }
                        }
                    }
                }
            }
        }
    

    zygote进程启动一个死循环,不断轮训fd数组接收命令
    mIsForkChild为true时,退出循环并且返回到main()方法中然后执行command.run()方法
    什么时候mIsForkChild为true呢,只有在调用Zygote.forkAndSpecialize()才会设置为true
    而Zygote.forkAndSpecialize()方法主要的作用是fork出第三方进程,如用户的app进程。这个后续再分析

    mIsForkChild为false时,表明当前一直处在死循环中,不断地轮训检测是否有socket连接。

    至此。zygote进程准备完毕。

    system_server进程

    回到刚才ZygoteInit::forkSystemServer()方法,上述分析过后,此时运行在子进程(system_server进程)
    接下来将执行handleSystemServerProcess()最终会调用:ZygoteInit::zygoteInit()方法:

        public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
    
            RuntimeInit.redirectLogStreams();
    
            RuntimeInit.commonInit();
            ZygoteInit.nativeZygoteInit();
            return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
        }
    
    

    接下来看看:

        protected static final void commonInit() {
            if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
    
            /*
             * set handlers; these apply to all threads in the VM. Apps can replace
             * the default handler, but not the pre handler.
             */
            Thread.setUncaughtExceptionPreHandler(new LoggingHandler());
            Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler());
    
            /*
             * Install a TimezoneGetter subclass for ZoneInfo.db
             */
            TimezoneGetter.setInstance(new TimezoneGetter() {
                @Override
                public String getId() {
                    return SystemProperties.get("persist.sys.timezone");
                }
            });
            TimeZone.setDefault(null);
    
            /*
             * Sets handler for java.util.logging to use Android log facilities.
             * The odd "new instance-and-then-throw-away" is a mirror of how
             * the "java.util.logging.config.class" system property works. We
             * can't use the system property here since the logger has almost
             * certainly already been initialized.
             */
            LogManager.getLogManager().reset();
            new AndroidConfig();
    
    
            initialized = true;
        }
    
    
    

    通过commonInit这个方法,我们也可以知道每个app默认的线程异常处理器是在这里设置,由Android系统提供的KillApplicationHandler

    接下来的这句: ZygoteInit.nativeZygoteInit(),最终会调用到jni方法:

        static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
    {
        //gCurRuntime就是上面分析AppRuntime对象,onZygoteInit是一个虚函数,具体实现在AppRuntime
        gCurRuntime->onZygoteInit();
    }
    
    virtual void onZygoteInit()
     {
            sp<ProcessState> proc = ProcessState::self();
            ALOGV("App process: starting thread pool.\n");
            //启动线程池
            proc->startThreadPool();
     }
    

    接下来我们看看 RuntimeInit::applicationInit()

    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
                ClassLoader classLoader) {
            // If the application calls System.exit(), terminate the process
            // immediately without running any shutdown hooks.  It is not possible to
            // shutdown an Android application gracefully.  Among other things, the
            // Android runtime shutdown hooks close the Binder driver, which can cause
            // leftover running threads to crash before the process actually exits.
            nativeSetExitWithoutCleanup(true);
    
            // We want to be fairly aggressive about heap utilization, to avoid
            // holding on to a lot of memory that isn't needed.
            VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
            VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
            
            final Arguments args = new Arguments(argv);
    
            // Remaining arguments are passed to the start class's static main
            return findStaticMain(args.startClass, args.startArgs, classLoader);
        }
    
    

    startClass在上述分析为:”com.android.server.SystemServer“
    findStaticMain方法主要是通过反射找到类的main(),然后包装成一个runnable对象,返回到最开始调用逻辑:

            if (startSystemServer) {
                    Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
    
                    // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                    // child (system_server) process.
                    if (r != null) {
                        r.run();
                        return;
                    }
                }
                
    

    执行完runnable.run实际是执行SystemServer.main()

    SystemServer.java

       /**
         * The main entry point from zygote.
         */
        public static void main(String[] args) {
            new SystemServer().run();
        }
    
        public SystemServer() {
            // Check for factory test mode.
            mFactoryTestMode = FactoryTest.getMode();
            // Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
            mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
        }
    
        private void run() {
            try {
    
                //
                // Default the timezone property to GMT if not set.
                //
                String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
                if (timezoneProperty == null || timezoneProperty.isEmpty()) {
                    Slog.w(TAG, "Timezone not set; setting to GMT.");
                    SystemProperties.set("persist.sys.timezone", "GMT");
                }
                    ...
                    ...
    
                // The system server should never make non-oneway calls
                Binder.setWarnOnBlocking(true);
    
    
          
                // Mmmmmm... more memory!
                VMRuntime.getRuntime().clearGrowthLimit();
    
                // The system server has to run all of the time, so it needs to be
                // as efficient as possible with its memory usage.
                VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
    
                // Some devices rely on runtime fingerprint generation, so make sure
                // we've defined it before booting further.
                Build.ensureFingerprintProperty();
    
                // Within the system server, it is an error to access Environment paths without
                // explicitly specifying a user.
                Environment.setUserRequired(true);
    
                // Within the system server, any incoming Bundles should be defused
                // to avoid throwing BadParcelableException.
                BaseBundle.setShouldDefuse(true);
    
                // Ensure binder calls into the system always run at foreground priority.
                BinderInternal.disableBackgroundScheduling(true);
    
                // Increase the number of binder threads in system_server
                BinderInternal.setMaxThreads(sMaxBinderThreads);
    
                // Prepare the main looper thread (this thread).
                android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
                android.os.Process.setCanSelfBackground(false);
                Looper.prepareMainLooper();
    
                // Initialize native services.
                System.loadLibrary("android_servers");
    
                // Check whether we failed to shut down last time we tried.
                // This call may not return.
                performPendingShutdown();
    
                // Initialize the system context.
                createSystemContext();
    
                // Create the system service manager.
                mSystemServiceManager = new SystemServiceManager(mSystemContext);
                mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
                LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
                // Prepare the thread pool for init tasks that can be parallelized
                SystemServerInitThreadPool.get();
            } finally {
                traceEnd();  // InitBeforeStartServices
            }
    
            // Start services.
            try {
                traceBeginAndSlog("StartServices");
                startBootstrapServices();
                startCoreServices();
                startOtherServices();
                SystemServerInitThreadPool.shutdown();
            } catch (Throwable ex) {
                Slog.e("System", "******************************************");
                Slog.e("System", "************ Failure starting system services", ex);
                throw ex;
            } finally {
                traceEnd();
            }
    
    
            // Loop forever.
            Looper.loop();
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
           
    
    
    1. Looper.prepareMainLooper() // 创建Looper
    2. createSystemContext() // 通过ActivityThread.systemMain()创建SystemContext
    3. 实例化SystemServiceManager //管理一系列的service启动
    4. startXXXXService()创建一系列的Service并注册进SystemServiceManager并执行onStart()方法启动

    其中我们熟知的ActivityManagerService,PackageManagerService....都是在此方法执行
    所以这堆service都是运行在系统的system_server进程。

    App进程

    app进程最终通过ActivityManagerService的调用来到这个方法里面

    
     private final void startProcessLocked(ProcessRecord app, String hostingType,
                String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
          ...
                // the PID of the new process, or else throw a RuntimeException.
                boolean isActivityProcess = (entryPoint == null);
                if (entryPoint == null) entryPoint = "android.app.ActivityThread";
                ProcessStartResult startResult;
                if (hostingType.equals("webview_service")) {
                    startResult = startWebView(entryPoint,
                            app.processName, uid, uid, gids, debugFlags, mountExternal,
                            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                            app.info.dataDir, null, entryPointArgs);
                } else {
                    startResult = Process.start(entryPoint,
                            app.processName, uid, uid, gids, debugFlags, mountExternal,
                            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                            app.info.dataDir, invokeWith, entryPointArgs);
                }
    
    
    }
    
    

    注意:entryPoint是"android.app.ActivityThread"

    Process.java

    
        public static final ProcessStartResult start(final String processClass,
                                      final String niceName,
                                      int uid, int gid, int[] gids,
                                      int runtimeFlags, int mountExternal,
                                      int targetSdkVersion,
                                      String seInfo,
                                      String abi,
                                      String instructionSet,
                                      String appDataDir,
                                      String invokeWith,
                                      String[] zygoteArgs) {
            return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                        runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                        abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
        }
    
    

    最终又会调到ZygoteProcess中

        public final Process.ProcessStartResult start(final String processClass,
                                                      final String niceName,
                                                      int uid, int gid, int[] gids,
                                                      int runtimeFlags, int mountExternal,
                                                      int targetSdkVersion,
                                                      String seInfo,
                                                      String abi,
                                                      String instructionSet,
                                                      String appDataDir,
                                                      String invokeWith,
                                                      String[] zygoteArgs) {
            try {
                return startViaZygote(processClass, niceName, uid, gid, gids,
                        runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                        abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
                        zygoteArgs);
            } catch (ZygoteStartFailedEx ex) {
                Log.e(LOG_TAG,
                        "Starting VM process through Zygote failed");
                throw new RuntimeException(
                        "Starting VM process through Zygote failed", ex);
            }
        }
    
    

    再看看看startViaZygote是个什么鬼

        private Process.ProcessStartResult startViaZygote(final String processClass,
                                                          final String niceName,
                                                          final int uid, final int gid,
                                                          final int[] gids,
                                                          int runtimeFlags, int mountExternal,
                                                          int targetSdkVersion,
                                                          String seInfo,
                                                          String abi,
                                                          String instructionSet,
                                                          String appDataDir,
                                                          String invokeWith,
                                                          boolean startChildZygote,
                                                          String[] extraArgs)
                                                          throws ZygoteStartFailedEx {
            ArrayList<String> argsForZygote = new ArrayList<String>();
        ...
        ...
    
            argsForZygote.add(processClass);
    
            if (extraArgs != null) {
                for (String arg : extraArgs) {
                    argsForZygote.add(arg);
                }
            }
    
            synchronized(mLock) {
                return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
            }
        }
    

    首先会调用openZygoteSocketIfNeeded

      private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
            Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
    
            if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
                try {
                    //与zygote进程连接
                    primaryZygoteState = ZygoteState.connect(mSocket);
                } catch (IOException ioe) {
                    throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
                }
                maybeSetApiBlacklistExemptions(primaryZygoteState, false);
                maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
            }
            if (primaryZygoteState.matches(abi)) {
                return primaryZygoteState;
            }
    
            // The primary zygote didn't match. Try the secondary.
            if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
                try {
                    secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
                } catch (IOException ioe) {
                    throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
                }
                maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
                maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
            }
    
            if (secondaryZygoteState.matches(abi)) {
                return secondaryZygoteState;
            }
    
            throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
        }
    
    

    经过这一步就将数据通过socket发送到server端(zygote进程),再看回顾一下,在分析ZygoteServer时的一段代码:

                // The select loop returns early in the child process after a fork and
                // loops forever in the zygote.
                caller = zygoteServer.runSelectLoop(abiList);
      
            // We're in the child process and have exited the select loop. Proceed to execute the
            // command.
           // app进程最终将会走到这里
            if (caller != null) {
                caller.run();
            }
    
    

    caller又是个什么东西?
    zygoteServer在runSeleteLoop中,此时收到客户端(app进程)发送来的请求,会调用processOneCommand方法

     Runnable processOneCommand(ZygoteServer zygoteServer) {
            String args[];
            Arguments parsedArgs = null;
            FileDescriptor[] descriptors;
    
            ....
          ...
    
            fd = null;
            // fork进程
            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
                    parsedArgs.instructionSet, parsedArgs.appDataDir);
    
            try {
                if (pid == 0) {
                    // in child
                    zygoteServer.setForkChild();
    
                    zygoteServer.closeServerSocket();
                    IoUtils.closeQuietly(serverPipeFd);
                    serverPipeFd = null;
    
                    return handleChildProc(parsedArgs, descriptors, childPipeFd,
                            parsedArgs.startChildZygote);
                } else {
                    // In the parent. A pid < 0 indicates a failure and will be handled in
                    // handleParentProc.
                    IoUtils.closeQuietly(childPipeFd);
                    childPipeFd = null;
                    handleParentProc(pid, descriptors, serverPipeFd);
                    return null;
                }
            } finally {
                IoUtils.closeQuietly(childPipeFd);
                IoUtils.closeQuietly(serverPipeFd);
            }
        }
    
    

    fork子进程,然后再调用handleChildProc方法

    private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
                FileDescriptor pipeFd, boolean isZygote) {
                ...
                if (!isZygote) {
                    // App进程将会调用到这里
                    return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
                            null /* classLoader */);
                } else {
                    return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
                            parsedArgs.remainingArgs, null /* classLoader */);
                }
            }
    
    

    此时的流程已经和前面分析提到的forkZygoteServer的后续流程一样,将会通过反射调用startClass的main()
    只不过这里的startClass是android.app.ActivityThread了,此后创建MainLooper,makeApplication,Activity,Service。。。

    总结一张图就是:

    zygote.jpg

    相关文章

      网友评论

          本文标题:Android启动流程

          本文链接:https://www.haomeiwen.com/subject/yskquqtx.html