精华内容
下载资源
问答
  • ZYGOTE
    千次阅读
    2022-03-20 15:11:59

    Zygote 进程初始化完成后,会化身为守护进程来执行启动应用程序的任务。下面是启动时序图

    在这里插入图片描述

    注册 Zygote 的 socket

    • ZygoteInit 的 main() 方法首先调用 registerServerSocketFromEnv() 来创建一个本地 socket,接着调用 runSelectLoop() 来进入等待 socket 连接的循环中。
    • registerServerSocketFromEnv() 方法如下
        void registerServerSocketFromEnv(String socketName) {
            if (mServerSocket == null) {
                int fileDesc;
                final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
                try {
                    String env = System.getenv(fullSocketName);
                    fileDesc = Integer.parseInt(env);
                } catch (RuntimeException ex) {
                    throw new RuntimeException(fullSocketName + " unset or invalid", ex);
                }
    
                try {
                    FileDescriptor fd = new FileDescriptor();
                    fd.setInt$(fileDesc);
                    mServerSocket = new LocalServerSocket(fd);
                    mCloseSocketFd = true;
                } catch (IOException ex) {
                    throw new RuntimeException(
                            "Error binding to local socket '" + fileDesc + "'", ex);
                }
            }
        }
    
    registerServerSocketFromEnv 通过设置环境变量 ANDROID_SOCKET_ 来获取 socket句柄。Zygote 在 init.rc 中定义 init.zygote32(或其他init.zygote32_64等) 有一句话 
    
    socket zygote stream 660 root system
    
    Init 进程会通过这条选项来创建一个 AF_UNIX 的 socket,并把它的句柄放到环境变量 ANDROID_SOCKET_zygote 中,这个环境变量后面的 zygote 就是选项中的名字。
    
    得到句柄后将通过 FileDescriptor fd = new FileDescriptor();  生成一个 FileDescriptor 对象,然后在通过mServerSocket = new LocalServerSocket(fd); 生成一个本地服务 socket,它的值将保存在全局 mServerSocket 中。
    

    请求启动应用

    android 启动一个新的进程是在 ActivityManagerService 中完成的,可能会有多种原因导致系统启动一个新的进程,最终在 ActivityManagerService 中都是通过调用方法 startProcessLocked() 来完成这一过程。startProcessLocked() 准备好参数后,会调用 Process 的 start() 方法来启动应用。部分代码如下
    
        private ProcessStartResult startProcess(String hostingType, String entryPoint,
                ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
                String seInfo, String requiredAbi, String instructionSet, String invokeWith,
                long startTime) {
                	// .... 其他代码省略
           		 	// 会调用  Process.start 开启应用
                    startResult = Process.start(entryPoint,
                            app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                            app.info.dataDir, invokeWith,
                            new String[] {PROC_START_SEQ_IDENT + app.startSeq});
    
    				//... 
        }
    
    Process.start() 的第一个参数是String entryPoint,如果往上查找会发现 entryPoint 的定义为 final String entryPoint = "android.app.ActivityThread";  就是应用启动后执行的入口类。
    
    Process.start() 实际上走的是 ZygoteProcess.start() 方法。方法如下:processClass 就是 android.app.ActivityThread
    
        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() 方法,将进程的启动参数保存到argsForZygote,最后调用zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    

    将应用程序启动的参数发送到 Zygote 进程,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>();
    
            // --runtime-args, --setuid=, --setgid=,
            // and --setgroups= must go first
            argsForZygote.add("--runtime-args");
            argsForZygote.add("--setuid=" + uid);
            argsForZygote.add("--setgid=" + gid);
            argsForZygote.add("--runtime-flags=" + runtimeFlags);
            if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
                argsForZygote.add("--mount-external-default");
            } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
                argsForZygote.add("--mount-external-read");
            } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
                argsForZygote.add("--mount-external-write");
            }
            argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
    
            // --setgroups is a comma-separated list
            if (gids != null && gids.length > 0) {
                StringBuilder sb = new StringBuilder();
                sb.append("--setgroups=");
    
                int sz = gids.length;
                for (int i = 0; i < sz; i++) {
                    if (i != 0) {
                        sb.append(',');
                    }
                    sb.append(gids[i]);
                }
    
                argsForZygote.add(sb.toString());
            }
    
            if (niceName != null) {
                argsForZygote.add("--nice-name=" + niceName);
            }
    
            if (seInfo != null) {
                argsForZygote.add("--seinfo=" + seInfo);
            }
    
            if (instructionSet != null) {
                argsForZygote.add("--instruction-set=" + instructionSet);
            }
    
            if (appDataDir != null) {
                argsForZygote.add("--app-data-dir=" + appDataDir);
            }
    
            if (invokeWith != null) {
                argsForZygote.add("--invoke-with");
                argsForZygote.add(invokeWith);
            }
    
            if (startChildZygote) {
                argsForZygote.add("--start-child-zygote");
            }
    
            argsForZygote.add(processClass);
    
            if (extraArgs != null) {
                for (String arg : extraArgs) {
                    argsForZygote.add(arg);
                }
            }
    
            synchronized(mLock) {
                return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
            }
        }
    
    上面代码最后调用了 zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote) 第一个参数如下调用了openZygoteSocketIfNeeded方法,建立 socket连接并且返回 ZygoteState,对于 LocalSocket 直接通过字符串作为地址进行连接就可以通信。
    
    // 如果socket没有连接,则尝试连接socket,如果已经打开了socket则什么都不做。
    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
            Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
    
            if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
                try {
                    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);
        }
    

    处理启动应用请求

     之前提过,ZygoteInit 类的 main方法最后调用了  zygoteServer.runSelectLoop(abiList); 开始了监听和接收消息的环节。
     当 (pollFds[i].revents & POLLIN) == 0 结果 为 false 代表有事件的请求到来,则调用 acceptCommandPeer() 来和客户端建立连接,然后把这个连接添加到监听数组中,等待socket的命令到来。接到命令后会处理参数,处理结束后会断开连接并且移除监听。
    
    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);
                            // processOneCommand 方法处理读取的命令 处理完后面会断开链接,并从监听列表中移除
                            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);
                                }
                            }
                        }
                        // 。。。
                }
            }
        }
    

    fork() 应用进程

    ZygoteConnnect 类中的 processOneCommand 负责创建子进程,首先调用args = readArgumentList(); 从 socket 中读入多个参数,参数样式为 “--setuid=1” 行与行之间用 /r /n 分割,读取完成后传入新建的 Arguments 对象 并调用parseArgs(args);解析成参数列表。
    
    解析参数之后还会对参数进行校验和设置。
    
    		// 检查用户是否有权利指定进程用户id,组id和所属的组,以及一些安全检查等。
    		applyUidSecurityPolicy(parsedArgs, peer);
            applyInvokeWithSecurityPolicy(parsedArgs, peer);
    
            applyDebuggerSystemProperty(parsedArgs);
            applyInvokeWithSystemProperty(parsedArgs);
    
    上面检测通过后,processOneCommand 会调用下面代码来 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);
    
    
    最终会调用 native 层的 nativeForkAndSpecialize() 的函数来完成 fork 操作
    
    native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int runtimeFlags,
              int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
              int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir);
    
    nativeForkAndSpecialize() 函数的主要工作:
    - fork() 出子进程
    - 在子进程中挂载 external storage
    - 在子进程中设置用户 Id、组Id、所属进程id
    - 在子进程中执行系统调用 setrlimit 来设置系统资源限制
    - 在子进程中执行系统调用 capset 来设置进程的权限
    - 在子进程中设置应用上下文
    
    native 返回 Java 层后,processOneCommand 方法继续执行,如果 pid==0 则在父进程中,否则在子进程中。
    
    			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;
                }
    

    子进程初始化

    上面讲了如果是在子进程中,则执行 handleChildProc() 函数。来完成子进程的初始化,代码如下
    
    private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
                FileDescriptor pipeFd, boolean isZygote) {
            /**
             * By the time we get here, the native code has closed the two actual Zygote
             * socket connections, and substituted /dev/null in their place.  The LocalSocket
             * objects still need to be closed properly.
             */
    		// 首先关闭了 socket 连接
            closeSocket();
            if (descriptors != null) {
                try {
                    Os.dup2(descriptors[0], STDIN_FILENO);
                    Os.dup2(descriptors[1], STDOUT_FILENO);
                    Os.dup2(descriptors[2], STDERR_FILENO);
    
                    for (FileDescriptor fd: descriptors) {
                        IoUtils.closeQuietly(fd);
                    }
                } catch (ErrnoException ex) {
                    Log.e(TAG, "Error reopening stdio", ex);
                }
            }
    
            if (parsedArgs.niceName != null) {
                Process.setArgV0(parsedArgs.niceName);
            }
    
            // End of the postFork event.
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            if (parsedArgs.invokeWith != null) {
                WrapperInit.execApplication(parsedArgs.invokeWith,
                        parsedArgs.niceName, parsedArgs.targetSdkVersion,
                        VMRuntime.getCurrentInstructionSet(),
                        pipeFd, parsedArgs.remainingArgs);
    
                // Should not get here.
                throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
            } else {
                if (!isZygote) {
                    return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
                            null /* classLoader */);
                } else {
                    return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
                            parsedArgs.remainingArgs, null /* classLoader */);
                }
            }
        }
    
    parsedArgs.invokeWith 普遍为Null,如果不为 Null 则通过 exec 方式启动 app_process 进程来执行Java类(通过执行 exec 的区别前面文章有讲过,fork + exec 和 单独 fork 不执行 exec 的区别)。
    正常情况会调用 ZygoteInit.zygoteInit ,主要执行的方法 是 RuntimeInit.commonInit,ZygoteInit.nativeZygoteInit() 和 RuntimeInit.applicationInit
    
        public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
            if (RuntimeInit.DEBUG) {
                Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
            }
    
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
            RuntimeInit.redirectLogStreams();
    
            RuntimeInit.commonInit();
            ZygoteInit.nativeZygoteInit();
            return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
        }
    
    • RuntimeInit.commonInit(); 方法
    protected static final void commonInit() {
            LoggingHandler loggingHandler = new LoggingHandler();
            // 设置 UncaughtException 的处理方法
            Thread.setUncaughtExceptionPreHandler(loggingHandler);
            Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
    		// 设置时区
            TimezoneGetter.setInstance(new TimezoneGetter() {
                @Override
                public String getId() {
                    return SystemProperties.get("persist.sys.timezone");
                }
            });
            TimeZone.setDefault(null);
            // 重制 Log 系统
            LogManager.getLogManager().reset();
            new AndroidConfig();
            // 设置 http.agent 属性
            String userAgent = getDefaultUserAgent();
            System.setProperty("http.agent", userAgent);
            NetworkManagementSocketTagger.install();
            String trace = SystemProperties.get("ro.kernel.android.tracing");
            if (trace.equals("1")) {
                Slog.i(TAG, "NOTE: emulator trace profiling enabled");
                Debug.enableEmulatorTraceOutput();
            }
    
            initialized = true;
        }
    
    • ZygoteInit.nativeZygoteInit(); 方法
      这个是 native 方法 private static final native void nativeZygoteInit(); 调用的是 AndroidRuntime.cpp中的方法
    
    static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
    {
        gCurRuntime->onZygoteInit();
    }
    
    
    gCurRuntime 是 AppRuntime 的全局指针,它的 onZygoteInit() 函数如下:主要是初始化了 Binder 环境,这样应用就可以使用 Binder了。
    
        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);
    
            // The end of of the RuntimeInit event (see #zygoteInit).
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    
            // Remaining arguments are passed to the start class's static main
            // findStaticMain 内部的 Run 方法通过 invoke 执行Java层的 main 方法
            return findStaticMain(args.startClass, args.startArgs, classLoader);
        }
    
    findStaticMain 经过一系列的处理最后会调用到 MethodAndArgsCaller 返回 Runnable,执行run方法后执行的是下面方法,mMethod 实际上是 main 方法。
    
    
     // Method m;
     //       try {
     //           m = cl.getMethod("main", new Class[] { String[].class });
    
     mMethod.invoke(null, new Object[] { mArgs });
    
    接下来就进入了应用本身的启动流程了。
    

    预加载系统类和资源

    为了加快应用程序的启动,Android把系统常用的 Java 类和一部分 Framework 的资源在 zygote 进程中加载,这些预加载的类和资源在所有经 Zygote fork出的进程中都是共享的。
    

    在这里插入图片描述

    ZygoteInit 在 main() 方法中调用的 preload(bootTimingsTraceLog); 加载系统类,系统资源和OpenGL等方法初始化如下
    
    static void preload(TimingsTraceLog bootTimingsTraceLog) {
            beginIcuCachePinning();
          
            preloadClasses();
          
            preloadResources();
         
            nativePreloadAppProcessHALs();
          
            preloadOpenGL();
           
            preloadSharedLibraries();
            preloadTextResources();
            
            WebViewFactory.prepareWebViewInZygote();
            endIcuCachePinning();
            warmUpJcaProviders();
            sPreloadComplete = true;
        }
    
    • 预加载 Java 类

      系统的 Java 类会频繁的执行,因此,需要把类的信息预先加载到系统内存中,并在所有应用进程中共享,Android将所有需要预加载的类放到了本地文件 preloaded-classes中,android9的目录位于 frameworks/base/config/preloaded-classes

    android.R$styleable
    android.accessibilityservice.AccessibilityServiceInfo
    android.accessibilityservice.AccessibilityServiceInfo$1
    android.accounts.Account
    android.accounts.Account$1
    android.accounts.AccountManager
    android.accounts.AccountManager$1
    android.accounts.AccountManager$10
    android.accounts.AccountManager$11
    android.accounts.AccountManager$18
    android.accounts.AccountManager$2
    android.accounts.AccountManager$20
    android.accounts.IAccountManagerResponse
    android.accounts.IAccountManagerResponse$Stub
    android.accounts.OnAccountsUpdateListener
    android.accounts.OperationCanceledException
    android.animation.AnimationHandler
    android.animation.AnimationHandler$1
    android.animation.AnimationHandler$AnimationFrameCallback
    android.animation.AnimationHandler$AnimationFrameCallbackProvider
    
    .....
    
    加载这些类的方法是 preloadClasses() ,流程如下
    
        private static void preloadClasses() {
            final VMRuntime runtime = VMRuntime.getRuntime();
    		// 首先获取一个 FileInputStream 通过流读取文件内容
            InputStream is;
            try {
                is = new FileInputStream(PRELOADED_CLASSES);
            } catch (FileNotFoundException e) {
                Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
                return;
            }
    		// 。。。。
    		while ((line = br.readLine()) != null) {
                    // Skip comments and blank lines.
                    line = line.trim();
                    // 忽略掉注释
                    if (line.startsWith("#") || line.equals("")) {
                        continue;
                    }
    
                    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
                    try {
                        if (false) {
                            Log.v(TAG, "Preloading " + line + "...");
                        }
                        // 然后通过 Class.forName 装载类的信息(它不会创建一个对象)
                        Class.forName(line, true, null);
                        count++;
                    } 
    	//。。。。
        }
    
    • 预加载资源
    private static void preloadResources() {
            final VMRuntime runtime = VMRuntime.getRuntime();
    
            try {
                mResources = Resources.getSystem();
                mResources.startPreloading();
                if (PRELOAD_RESOURCES) {
                    Log.i(TAG, "Preloading resources...");
    
                    long startTime = SystemClock.uptimeMillis();
                    TypedArray ar = mResources.obtainTypedArray(
                            com.android.internal.R.array.preloaded_drawables);
                    int N = preloadDrawables(ar);
                    ar.recycle();
                    Log.i(TAG, "...preloaded " + N + " resources in "
                            + (SystemClock.uptimeMillis()-startTime) + "ms.");
    
                    startTime = SystemClock.uptimeMillis();
                    ar = mResources.obtainTypedArray(
                            com.android.internal.R.array.preloaded_color_state_lists);
                    N = preloadColorStateLists(ar);
                    ar.recycle();
                    Log.i(TAG, "...preloaded " + N + " resources in "
                            + (SystemClock.uptimeMillis()-startTime) + "ms.");
    
                    if (mResources.getBoolean(
                            com.android.internal.R.bool.config_freeformWindowManagement)) {
                        startTime = SystemClock.uptimeMillis();
                        ar = mResources.obtainTypedArray(
                                com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
                        N = preloadDrawables(ar);
                        ar.recycle();
                        Log.i(TAG, "...preloaded " + N + " resource in "
                                + (SystemClock.uptimeMillis() - startTime) + "ms.");
                    }
                }
                mResources.finishPreloading();
            } catch (RuntimeException e) {
                Log.w(TAG, "Failure preloading resources", e);
            }
        }
    
    
    更多相关内容
  • zygote

    2019-07-30 01:26:20
    NULL 博文链接:https://yishizhu.iteye.com/blog/843632
  • Zygote解析

    2021-01-03 22:15:18
    一、Zygote简介 init会创建Zygote进程,SystemServer进程和应用进程都是Zygote(孵化器)fock(复制进程)出来的。所以有必要了解下Zygote的流程。 二、Zygote启动流程 分析Zygote启动首先会调用ZygoteInit的main函数...
  • 在Android系统中,所有的应用程序进程,以及用来运行系统关键服务的System进程都是由zygote进程负责创建的。因此,我们将它称为进程孵化器。zygote进程是通过复制自身的方式来创建System进程和应用程序进程的。由于...
  • Zygote是一个个人探索项目,旨在可能改进软件的开发方式。 目前,该存储库仅包含目标编写的内容,但很快就会有一些代码出现。 本文档介绍了5个重点领域: 惯用翻译-设计一种可以翻译成任意一种语言的语言,其结果...
  • Zygote可以说是Android开发面试很高频的一道问题,但总有小伙伴在回答这道问题总不能让面试满意, 在这你就要搞清楚面试问你对Zygote的理解时,面试官最想听到的和其实想问的应该是哪些?下面我们通过以下几点来剖析...
  • Zygote进程

    2022-06-19 18:45:33
    Zygote进程 android12-release Android系统启动 init进程 – 干了啥事 system/core/init/init.cpp system/core/rootdir/init.rc frameworks/base/cmds/app_process/app_main.cpp frameworks/base/core/jni/Android...

    Zygote进程

    android12-release
    Android系统启动
    init进程 – 干了啥事


    system/core/init/init.cpp
    system/core/rootdir/init.rc
    frameworks/base/cmds/app_process/app_main.cpp
    frameworks/base/core/jni/AndroidRuntime.cpp
    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    frameworks/base/core/java/com/android/internal/os/Zygote.java


    Zygote.rc文件

    Zygote是由init进程通过解析init.zygote.rc文件而创建的,zygote所对应的可执行程序app_process,所对应的源文件是App_main.cpp,进程名为zygote。
    在这里插入图片描述
    init.zygote32.rc文件

    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
        socket usap_pool_primary stream 660 root system
        onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
        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
        critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
    

    init.zygote64.rc文件

    service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
        class main
        priority -20
        user root
        group root readproc reserved_disk
        socket zygote stream 660 root system
        socket usap_pool_primary stream 660 root system
        onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
        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
        critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
    

      创建叫"zygote"的service结构体;
      创建用于"socket"通信的socketinfo结构体;
      创建"onrestart"的action结构体。Zygote进程能够重启的地方。


      Zygote服务会随着main class的启动而启动,zygote所对应的可执行文件是/system/bin/app_processXX,通过调用pid =fork()创建子进程,通过execve(svc->args[0], (char**)svc->args, (char**) ENV),进入App_main.cpp的main()函数。

    init 解析 /system/etc/init/hw/init.${ro.zygote}.rc 文件启动Zygote进程
    在这里插入图片描述

    Zygote启动过程

    app_main#main

    frameworks/base/cmds/app_process/app_main.cpp

    • strcmp(arg, "--zygote") zygote为true,niceName = ZYGOTE_NICE_NAME区分32位、64位系统
    • strcmp(arg, "--start-system-server") startSystemServer为true
    • runtime.setArgv0(niceName.string(), true /* setProcName */);设置进程名
    • runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    #if defined(__LP64__)
    static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64";
    static const char ZYGOTE_NICE_NAME[] = "zygote64";
    #else
    static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist32";
    static const char ZYGOTE_NICE_NAME[] = "zygote";
    #endif
    
    int main(int argc, char* const argv[])
    {
    //。。。 。。。
        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;
            }
        }
    //。。。 。。。
            if (startSystemServer) {
                args.add(String8("start-system-server"));
            }
    //。。。 。。。
        if (!niceName.isEmpty()) {
            runtime.setArgv0(niceName.string(), true /* setProcName */);
        }
     
        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.");
        }
    }
    

    AndroidRuntime::start

    frameworks/base/core/jni/include/android_runtime/AndroidRuntime.h
    frameworks/base/core/jni/AndroidRuntime.cpp

    • primary_zygote = true
    • startVm()创建启动java虚拟机
    • startReg() register_jni_procs中JNI方法注册
    • env->CallStaticVoidMethod(startClass, startMeth, strArray) 这里startClass为"com.android.internal.os.ZygoteInit",startMeth为main()方法
    • free(slashClassName) 释放相应对象的内存空间
    void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
    {
    //。。。 。。。
        /*
         * 'startSystemServer == true' means runtime is obsolete and not run from
         * init.rc anymore, so we print out the boot start event here.
         */
        for (size_t i = 0; i < options.size(); ++i) {
            if (options[i] == startSystemServer) {
                primary_zygote = true;
               /* 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)));
            }
        }
    //。。。 。。。
        /* start the virtual machine */
        JniInvocation jni_invocation;
        jni_invocation.Init(NULL);
        JNIEnv* env;
        if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
            return;
        }
        onVmCreated(env);
    
        /*
         * Register android functions.
         */
        if (startReg(env) < 0) {
            ALOGE("Unable to register all android natives\n");
            return;
        }
    //。。。 。。。
        /*
         * Start VM.  This thread becomes the main thread of the VM, and will
         * not return until the VM exits.
         */
        char* slashClassName = toSlashClassName(className != NULL ? className : "");
        jclass startClass = env->FindClass(slashClassName);
        if (startClass == NULL) {
            ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
            /* keep going */
        } else {
            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);
    
    #if 0
                if (env->ExceptionCheck())
                    threadExitUncaughtException(env);
    #endif
            }
        }
        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");
    }
    

    JNI到Java层

    ZygoteInit.main

    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    • RuntimeInit.preForkInit()中RuntimeInit.enableDdms()
    • startSystemServer = true
    • zygoteServer = new ZygoteServer(isPrimaryZygote) 为Zygote注册socket
    • forkSystemServer() 启动SystemServer
    • caller = zygoteServer.runSelectLoop(abiList); 进入循环模式,Zygote采用高效的I/O多路复用机制,保证在没有客户端连接请求或数据处理时休眠,否则响应客户端的请求。等待AMS请求。
        public static void main(String[] argv) {
            ZygoteServer zygoteServer = null;
    
            // Mark zygote start. This ensures that thread creation will throw
            // an error.
            ZygoteHooks.startZygoteNoThreadCreation();
    
            // Zygote goes into its own process group.
            try {
                Os.setpgid(0, 0);
            } catch (ErrnoException ex) {
                throw new RuntimeException("Failed to setpgid(0,0)", ex);
            }
    
            Runnable caller;
            try {
                // Store now for StatsLogging later.
                final long startTime = SystemClock.elapsedRealtime();
                final boolean isRuntimeRestarted = "1".equals(
                        SystemProperties.get("sys.boot_completed"));
    
                String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
                TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
                        Trace.TRACE_TAG_DALVIK);
                bootTimingsTraceLog.traceBegin("ZygoteInit");
                RuntimeInit.preForkInit();
    
                boolean startSystemServer = false;
                String zygoteSocketName = "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)) {
                        zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
                    } else {
                        throw new RuntimeException("Unknown command line argument: " + argv[i]);
                    }
                }
    
                final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
                if (!isRuntimeRestarted) {
                    if (isPrimaryZygote) {
                        FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                                BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START,
                                startTime);
                    } else if (zygoteSocketName.equals(Zygote.SECONDARY_SOCKET_NAME)) {
                        FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                                BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SECONDARY_ZYGOTE_INIT_START,
                                startTime);
                    }
                }
    
                if (abiList == null) {
                    throw new RuntimeException("No ABI list supplied.");
                }
    
                // In some configurations, we avoid preloading resources and classes eagerly.
                // In such cases, we will preload things prior to our first fork.
                if (!enableLazyPreload) {
                    bootTimingsTraceLog.traceBegin("ZygotePreload");
                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                            SystemClock.uptimeMillis());
                    preload(bootTimingsTraceLog);
                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                            SystemClock.uptimeMillis());
                    bootTimingsTraceLog.traceEnd(); // ZygotePreload
                }
    
                // Do an initial gc to clean up after startup
                bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
                gcAndFinalize();
                bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
    
                bootTimingsTraceLog.traceEnd(); // ZygoteInit
    
                Zygote.initNativeState(isPrimaryZygote);
    
                ZygoteHooks.stopZygoteNoThreadCreation();
    
                zygoteServer = new ZygoteServer(isPrimaryZygote);
    
                if (startSystemServer) {
                    Runnable r = forkSystemServer(abiList, zygoteSocketName, 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;
                    }
                }
    
                Log.i(TAG, "Accepting command socket connections");
    
                // 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 fatal exception", ex);
                throw ex;
            } finally {
                if (zygoteServer != null) {
                    zygoteServer.closeServerSocket();
                }
            }
    
            // We're in the child process and have exited the select loop. Proceed to execute the
            // command.
            if (caller != null) {
                caller.run();
            }
        }
    

    forkSystemServer

    pid = Zygote.forkSystemServer准备参数并fork新进程,从上面可以看出SystemServer进程参数信息为uid=1000,gid=1000,进程名为sytem_server,

        private static Runnable forkSystemServer(String abiList, String socketName,
                ZygoteServer zygoteServer) {
    //。。。 。。。
            /* 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,1021,1023,"
                            + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
                    "--capabilities=" + capabilities + "," + capabilities,
                    "--nice-name=system_server",
                    "--runtime-args",
                    "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
                    "com.android.server.SystemServer",
            };
            ZygoteArguments parsedArgs;
    //。。。 。。。
                /* Request to fork the system server process */
                pid = Zygote.forkSystemServer(
                        parsedArgs.mUid, parsedArgs.mGid,
                        parsedArgs.mGids,
                        parsedArgs.mRuntimeFlags,
                        null,
                        parsedArgs.mPermittedCapabilities,
                        parsedArgs.mEffectiveCapabilities);
            } catch (IllegalArgumentException ex) {
                throw new RuntimeException(ex);
            }
    
            /* For child process */
            if (pid == 0) {
                if (hasSecondZygote(abiList)) {
                    waitForSecondaryZygote(socketName);
                }
    
                zygoteServer.closeServerSocket();
                return handleSystemServerProcess(parsedArgs);
            }
    
            return null;
        }
    

    frameworks/base/core/java/com/android/internal/os/Zygote.java

        static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
                int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
            ZygoteHooks.preFork();
    
            int pid = nativeForkSystemServer(
                    uid, gid, gids, runtimeFlags, rlimits,
                    permittedCapabilities, effectiveCapabilities);
    
            // Set the Java Language thread priority to the default value for new apps.
            Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
    
            ZygoteHooks.postForkCommon();
            return pid;
        }
    

    时序图

    在这里插入图片描述

    Zygote小结

    1. Zygote由init进程fork而来
    2. 创建AppRuntime调用start启动Zygote
    3. 设置创建JVM,并注册JNI方法
    4. 通过JNI调用ZygoteInit.main,进入java框架
    5. zygoteServer 为Zygote注册socket,通过zygoteServer.runSelectLoop等待AMS请求
    6. 启动SystemServer进程system_server
    展开全文
  • Android Zygote

    2022-06-17 11:30:15
    1.Zygote Zygote译为“受精卵”,是Android中SystemServer和几乎所有Java应用的孵化器。SystemServer和Java应用的父进程都是zygotezygote是一个很重要的服务进程,没有zygote就没有Android,Android的启动也离不...

    1.Zygote

    Zygote译为“受精卵”。在Android中,负责孵化新进程的这个进程就叫Zygote,其他的应用进程都是由它孵化的。由于安卓是Linux内核,安卓系统上运行的一切程序都是放在Dalvik虚拟机上的,Zygote也不例外,事实上,它是安卓运行的第一个Dalvik虚拟机进程。既然Zygote负责孵化其他的安卓进程,那么它自己是由谁孵化的呢?因为Android是基于Linux内核,那么Zygote当然就是Linux内核启动的用户级进程Init创建的了。

    60217847d1154b6aa634f5889c07a818.png

     Zygote进程在启动时会创建一个Dalvik虚拟机实例,每当它孵化一个新的应用程序进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面去,从而使每一个应用程序进程都有一个独立的Dalvik虚拟机实例。试想,如果每个应用程序在启动时都要单独运行和初始化一个虚拟机,会大大降低系统性能,因此Android首先创建一个zygote虚拟机,然后通过它孵化出其他的虚拟机进程,进而共享虚拟机内存和框架层资源,这样就大幅度提高了应用程序的启动和运行速度。

     

    zygote的作用:

    ​①创建并启动SystemServer进程

    ②fork新的应用进程

     

    Android中大多数应用进程和系统进程都是通过Zygote进程来生成的。Zygote为孵化的应用程序提供了几个基础资源:

    ①常用类:Android的java类库

    ②JNI函数

    ③主题资源:比如theme图片,占用10M+的内存空间,这些内存是系统共享的

    ④共享库

     

    2.zygote的启动

    zygote是由Init进程(pid=1)解析init.rc脚本启动的。Zygote进程在Init进程启动过程中被以service服务的形式启动。

    从rc文件中可以看出:

    ①zygote的进程优先级是最高的,priority被设成-20,主要是因为Android的启动非常依赖于SystemServer的启动,而SystemServer也是zygote fork出来的,因此需要将zygote优先级设成最高的。

    ②zygote在启动时创建了两个socket(zygote和usap_pool_primary),用于进程间的通信。

    ③zygote是Android非常重要的核心服务之一,当其因异常退出后,Init会将其重新启动,并将一些相关的节点和服务重新设置。

    zygote的启动实际上分成了两部分:SystemServer的启动、ZygoteServer的启动。两者前面是在同一个进程中执行的,当虚拟机创建完成后才正式分离。

     

    zygote是通过app_process启动,入口就是app_process的main函数:

    #frameworks/base/cmds/app_process/app_main.cpp

    int main(int argc, char* const argv[]) {

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

        …

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

        …

    }

    创建AndroidRuntime对象(AndroidRuntime继承自AppRuntime),这里面主要的动作就是启动虚拟机。然后在虚拟机中运行ZygoteInit,ZygoteInit是java写的,即这一步Zygote就从native世界进入到了Java世界。接下来的流程如下图:

    835bb781a5794b25bb27a8abf0cd409b.jpg

     Zygote的java世界入口就是ZygoteInit类的main方法:

    #frameworks/base/core/java/com/android/internal/os/ZygoteInit.java:

    public static void main(String argv[]) { 

        ……

        zygoteServer = new ZygoteServer( isPrimaryZygote); //1.创建ZygoteServer

          zygoteServer.registerServerSocket( socketName); //2.创建一个Server端的Socket

        preload(bootTimingsTraceLog); //3.加载进程的资源和类

        if (startSystemServer) {

            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); //4.启动SystemServer

            if (r != null) {

                r.run();

                return;

            }

        }

        //5.启动一个死循环监听来自Client端的消息

        caller = zygoteServer.runSelectLoop(abiList);

        if (caller != null) {

            caller.run();

        }

    }

    ZygoteInit的main()方法是Android启动中的第一个Java进程的主方法。它主要完成几件事情:

    ①注册一个socket

    在main方法里,通过registerServerSocket方法来创建一个Server端的socket,这个name为zygote的socket用于等待ActivityManagerService请求Zygote来创建新的应用程序进程。

    Zygote作为孵化器,跟其他进程间的通讯不是通过binder,而是通过socket。一旦有新进程需要运行,系统会通过这个socket跟Zygote通讯,由zygote完成进程孵化过程。

    ②预加载各类资源

    preload函数用于加载虚拟机运行时所需的各类资源。

    在ZygoteInit中,一般无特殊原因,都会调用preload()方法将Android Java层应用常用的资源预加装,其原因是:

    1)Android是基于Linux系统开发的,底层就是Linux操作系统,而Linux进程的fork机制有一个特点,就是写时拷贝机制,即fork出来的进程最初是共用一块内存,只有当发生写操作时,才会将对应的内存块进行拷贝修改,而一些只读的内存块则会所有fork出来的进程共享。

    2)preload()方法所加装的东西主要有以下几类:常用类文件、Resources资源、HALs资源、opengl、webview等。这些资源一般都是只读的,不会进行修改,而且是很多应用都可能会用到的。因此预先加载后所有由zygote fork出来的应用进程都能共用一块内存。

    0fe012d22aa34373ac026fe4da44cd21.jpg

     通过上图可以很容易理解在Zygote进程预加载系统资源后,然后通过它孵化出其他的虚拟机进程,进而共享虚拟机内存和框架层资源,这样大幅度提高应用程序的启动和运行速度。

    ③启动SystemServer

    b9ae6f20438346789ed239f35022cbfc.jpg 4718c8314bc94f2c9415d97e9834f27f.jpg

     SystemServer是通过forkSystemServer()方法fork出来并开始执行。

    private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) {

        int pid;

        pid = Zygote.forkSystemServer(

                    parsedArgs.mUid, parsedArgs.mGid,

                    parsedArgs.mGids,

                    parsedArgs.mRuntimeFlags,

                    null,

                    parsedArgs.mPermittedCapabilities,

                    parsedArgs.mEffectiveCapabilities);

        if (pid == 0) { //子进程

            zygoteServer.closeServerSocket();

            return handleSystemServerProcess( parsedArgs);

        }

        return null;

    }

    forkSystemServer()中主要做了两件事:①调用Zygote.forkSystemServer()方法fork一个新的进程出来。②fork()后的子进程是SystemServer进程,等待zygote的启动完成,然后执行真正的SystemServer代码。

    // Zygote.java

    public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {

        ZygoteHooks.preFork(); //将Daemons线程关掉,虚拟机进行一些copy前的处理

        // Resets nice priority for zygote process.

        resetNicePriority(); //将进程的优先级设回普通的级别

        int pid = nativeForkSystemServer( uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities); //调用native层方法fork一个新的进程。该方法主要调用Linux的fork系统调用,fork一个新的进程,子进程的pid为0,父进程返回子进程的pid值

        if (pid == 0) { //子进程

            Trace.setTracingEnabled(true, runtimeFlags);

        }

        ZygoteHooks.postForkCommon(); //重新启动Daemons线程,虚拟机进行copy后的处理

        return pid;

    }

    注:fork操作是不会将进程中所有线程拷贝的,只会拷贝当前线程。

    Daemons线程是指:①HeapTaskDaemon;②ReferenceQueueDaemon;③FinalizerDaemon;④FinalizerWatchdogDaemon。平时在trace文件(ANR或者其他方式获取的trace文件)中看到Java应用进程都会有这4个线程,这4个线程就是在这里创建的。

    再回到ZygoteInit.forkSystemServer()方法,此时两个进程都会返回到此处,然后两个进程到这就分道扬镳了。SystemServer进程将ZygoteServer的socket关闭,然后调用handleSystemServerProcess()方法去执行SystemServer的源码。

    handleSystemServerProcess()方法的核心代码:

    createSystemServerClassLoader();

    ClassLoader cl = sCachedSystemServerClassLoader;

     if (cl != null) {

          Thread.currentThread().setContextClassLoa der(cl);

     }

     return ZygoteInit.zygoteInit( parsedArgs.mTargetSdkVersion,parsedArgs.mRemainingArgs, cl);

    先获取classloader,并将其设置为root classloader。然后调用ZygoteInit.zygoteInit()方法去执行。

    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {

        RuntimeInit.commonInit();

        ZygoteInit.nativeZygoteInit(); //为进程创建Binder的环境(ProcessStatae)

        return RuntimeInit.applicationInit( targetSdkVersion, argv, classLoader); //执行传参进来的类的main()方法,这里传进来的类就是com.android.server.SystemServer

    }

    ZygoteInit.forkSystemServer()返回一个runnable,返回到ZygoteInit.main()方法后,SystemServer进程就会继续执行这个runnable。

    zygote在fork进程后,使用runnable的方式返回到main()方法后才执行的原因?减少线程堆栈的长度,因为fork后进行执行的内容与之前zygote的堆栈内容并无关系,因此不需要为每个进程都保留前面的堆栈信息,而且还能减少进程的堆栈容量限制。

    ④进入Loop循环 ZygoteServer.runSelectLoop

    当zygote进程返回到main()方法后,就会继续执行ZygoteServer.runSelectLoop()方法,这个方法是一个死循环,是不断进行循环执行命令的方法。执行runSelectLoop()方法是为了等待消息去创建应用进程。

    runSelectLoop()方法主要做两件事:

    ①每次循环都重新构建监听文件列表,主要是ZygoteServer的socket文件(ZygoteServer的socket和其他应用进程连接过来的socket)和usap文件节点。

    ②监听文件列表,并从中获取命令执行。

     

    一张图看看Zygote的启动流程:

    789a756232844da693dec72a474be40e.jpg

     

    dbeb367eb65049e0889173200bd8aaf0.png

    84ca3d8d2d704fc994fe1091a791448e.jpg

     

    3.总结

    Zygote创建Java世界的步骤:

    ①第一天:创建AppRuntime对象,并调用它的start。此后的活动则由AppRuntime来控制。

    ②第二天:调用startVm创建Java虚拟机,然后调用startReg来注册JNI函数。

    ③第三天:通过JNI调用com.android.internal.os.ZygoteInit类的main函数,从此进入了Java世界。然而在这个世界刚开创的时候,什么东西都没有。

    ④第四天:调用registerZygoteSocket,通过这个函数,它可以响应子孙后代的请求。同时Zygote调用preloadClasses和preloadResources,为Java世界添砖加瓦。

    ⑤第五天:Zygote觉得自己工作压力太大,便通过调用startSystemServer分裂一个子进程system_server来为Java世界服务。

    ⑥第六天:Zygote完成了Java世界的初创工作,它已经很满足了。下一步该做的就是调用runSelectLoopMode后,便沉沉地睡去了。

    ⑦以后的日子:Zygote随时守护在我们的周围,当接收到子孙后代的请求时,它会随时醒来,为它们工作。

    ⑧有一天,他的孩子SystemServer发送了个请求,Zygote苏醒,Zygote调用ZygoteConnection的runOnce函数。在runOnce方法中Zygote分裂了一个子进程(App进程),然后在调用handleChildProc方法在子进程中进行处理。

    ⑨然后继续沉睡,等待请求进行下一次分裂。

    6298a2cc63874bd9b3a42133eeaeaac6.png

     

     

    4.面试问题

    ①为何用socket而不是binder

    Zygote是通过fork来创建新进程的,而binder是多线程的,有可能造成死锁。

    在 POSIX 标准中,fork 的行为是这样的:复制整个用户空间的数据(通常使用 copy-on-write 的策略,所以可以实现的速度很快)以及所有系统对象, 然后仅复制当前线程到子进程。这里:所有父进程中别的线程,到了子进程中都是突然蒸发掉的。

    假如父进程在获取到锁的情况下,fork了一个子进程。子进程的内存中,这个锁的状态是上锁状态。子进程仅运行了fork所在的这个线程,其它线程没有运行,当它尝试获取锁时,就发生了死锁

    ②为何要通过Zygote来孵化程序,而不是由其他进程直接创建?

    主要有两个好处:

    1)缩短应用的启动时间

    无论哪个app,所有的虚拟机都必须按照某种一样的而且是确定的方式初始化。Zygote预加载了各种资源,创建了虚拟机。由Zygote创建的进程能够继承这些资源,不用再重新创建。加载app的类只是最后一步而已。

    2)优化共享内存

    所有虚拟机都是从Zygote fork出来的,所以特么能够享受到由内核实现的内存共享的优势。比如Zygote预加载的各类资源,比如theme主题图片,所有的进程都是共享的,在物理内存中只需要保存一份。

    ③Zygote这一设计有什么缺点?

    所有应用进程都是从同一个进程fork出来的,这会有效地破坏地址空间布局随机化,这一技术是对抗代码注入攻击的重要安全手段。

    展开全文
  • Zygote在Android系统扮演着不可或缺的角色,Android系统的启动首先需要Zygote参与,比如启动SystemService , 还有一个就是孵化应用的进程,比如我们创建一个Activity也是需要Zygote参与.  Zygote 启动分为两个部分: 1....
  • ptrace注入与zygote区别和联系.V2EEptrace注入与zygote区别和联系.V2EE
  • Zygote进程简介

    2021-12-20 16:56:30
    属性ro.zygote的值可能有:zygote32、zygote64、zygote32_64、zygote64_32。 3、init.zygote32.rc service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main ...

    本文基于Android_9.0、kernel_3.18源码

    zygote启动流程

    Android手机进程

    打开控制台,使用adb shell,然后执行ps -A命令;便可看到Android系统中运行的进程。PID是进程号,PPID是父进程号。PID越小启动越早。

    Android手机进程

    主要进程之间的关系

    通过梳理我们可以得到以下的关系图:
    进程关系

    init进程

    打开android手机后,会先启动bootloader引导程序,当kernel完成系统设置后,它会拉起init进程。init进程主要进行文件夹创建挂载、init.rc文件解析等操作。

    system/core/init/init.cpp
    system/core/rootdir/init.rc
    xref/system/core/rootdir/init.zygote32.rc

    1、init.cpp->main()

    int main(int argc, char** argv) {
        ...
        if (is_first_stage) {
            ...
            // 创建文件夹并挂载
            mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
            mkdir("/dev/pts", 0755);
            mkdir("/dev/socket", 0755);
            mount("devpts", "/dev/pts", "devpts", 0, NULL);
            ...
        }
        ...
        
        property_init(); // 初始化property
        
        process_kernel_dt(); // 加载dt的数据
        process_kernel_cmdline(); // 加载cmd的数据
        ...
    
        ActionManager& am = ActionManager::GetInstance();
        ServiceList& sm = ServiceList::GetInstance();
    
        // 加载启动脚本
        LoadBootScripts(am, sm);
    
        // 添加其他任务
        am.QueueEventTrigger("early-init");
        // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
        am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
        ...
    
        // 循环执行任务
        while (true) {
            // By default, sleep until something happens.
            int epoll_timeout_ms = -1;
            ...
    
            // 执行任务
            if (!(waiting_for_prop || Service::is_exec_service_running())) {
                am.ExecuteOneCommand();
            }
            if (!(waiting_for_prop || Service::is_exec_service_running())) {
                if (!shutting_down) {
                    auto next_process_restart_time = RestartProcesses();
    
                    // 如果有进程需要重启,设置超时时间
                    if (next_process_restart_time) {
                        epoll_timeout_ms = std::chrono::ceil<std::chrono::milliseconds>(*next_process_restart_time - boot_clock::now()).count();
                        if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
                    }
                }
    
                // 如果还有任务需要执行,设置超时为0
                if (am.HasMoreCommands()) epoll_timeout_ms = 0;
            }
    
            epoll_event ev;
            // epoll阻塞,等待唤醒、超时
            int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));
            ...
        }
    
        return 0;
    }
    

    查看main函数,它主要做了如下操作:

    <1>创建文件夹并挂载
    <2>初始化属性
    <3>解析init.rc文件
    <4>启动任务(Action)
    

    2、init.rc

    ...
    // 引入zygote.rc文件
    import /init.${ro.zygote}.rc
    ...
    
    # Mount filesystems and start core system services.
    on late-init
        ...
        # Now we can start zygote for devices with file based encryption
        trigger zygote-start
        ...
    
    ...
    

    在init.rc文件中,引入了init.zygote32.rc,并设置了zygote的启动时机。
    属性ro.zygote的值可能有:zygote32、zygote64、zygote32_64、zygote64_32。

    3、init.zygote32.rc

    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可执行文件,并携带参数 –zygote–start-system-server
    搜索源码,可以看到app_process目录下的文件,app_process可执行文件就是由app_main.cpp编译出来的。

    app_process文件夹

    zygote进程-native

    frameworks/base/cmds/app_process/app_main.cpp

    1、app_main.cpp->main()

    #if defined(__LP64__)
    static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64";
    static const char ZYGOTE_NICE_NAME[] = "zygote64";
    #else
    static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist32";
    static const char ZYGOTE_NICE_NAME[] = "zygote";
    #endif
    
    // service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    int main(int argc, char* const argv[]){
        ...
        // 实例化AppRuntime
        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    
        ...
        bool zygote = false;
        bool startSystemServer = false;
        bool application = false;
        String8 niceName;
        String8 className;
    
        // 解析参数,解析完毕后的值分别为
        // zygote = true
        // startSystemServer = true
        // niceName = ZYGOTE_NICE_NAME (zygote)
        // application = false
        // className = null
        ++i;
        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()) {
           ...
        } else {
            ...
            if (startSystemServer) {
                args.add(String8("start-system-server"));
            }
            ...
    
            String8 abiFlag("--abi-list=");
            abiFlag.append(prop);
            args.add(abiFlag);
    
            // 将剩余参数传递给ZygoteInit的main方法
            for (; i < argc; ++i) {
                args.add(String8(argv[i]));
            }
        }
    
        // 修改进程名称
        if (!niceName.isEmpty()) {
            runtime.setArgv0(niceName.string(), true /* setProcName */);
        }
    
        if (zygote) {
            runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
        } else if (className) {
            ...
        } else {
            ...
        }
    }
    
    void AndroidRuntime::setArgv0(const char* argv0, bool setProcName) {
        if (setProcName) {
            int len = strlen(argv0);
            if (len < 15) {
                pthread_setname_np(pthread_self(), argv0);
            } else {
                pthread_setname_np(pthread_self(), argv0 + len - 15);
            }
        }
        memset(mArgBlockStart, 0, mArgBlockLength);
        strlcpy(mArgBlockStart, argv0, mArgBlockLength);
    }
    

    首先, main方法会循环遍历传入的参数;
    然后, 通过setArgv0修改当前进程的名字为zygote;
    最后, 启动com.android.internal.os.ZygoteInit的main函数,将参数传递过去。

    2、AndroidRuntime.cpp->start()

    class AppRuntime : public AndroidRuntime{
        ...
    }
    
    // 开启Android虚拟机, 并调用className的main方法
    void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){
        ...
    
        // 检查rootDir
        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);
        }
    
        // 启动Android虚拟机
        JniInvocation jni_invocation;
        jni_invocation.Init(NULL);
        JNIEnv* env;
        if (startVm(&mJavaVM, &env, zygote) != 0) {
            return;
        }
        onVmCreated(env);
    
        // 注册andorid方法
        if (startReg(env) < 0) {
            ALOGE("Unable to register all android natives\n");
            return;
        }
    
        // 设置类名、参数
        jclass stringClass;
        jobjectArray strArray;
        jstring classNameStr;
    
        stringClass = env->FindClass("java/lang/String");
        assert(stringClass != NULL);
        strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
        assert(strArray != NULL);
        classNameStr = env->NewStringUTF(className);
        assert(classNameStr != NULL);
        env->SetObjectArrayElement(strArray, 0, classNameStr);
    
        for (size_t i = 0; i < options.size(); ++i) {
            jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
            assert(optionsStr != NULL);
            env->SetObjectArrayElement(strArray, i + 1, optionsStr);
        }
    
        char* slashClassName = toSlashClassName(className != NULL ? className : "");
        // 找到class
        jclass startClass = env->FindClass(slashClassName);
        if (startClass == NULL) {
            ...
        } else {
            // 找到main方法
            jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
            if (startMeth == NULL) {
                ...
            } else {
                // 调用方法
                env->CallStaticVoidMethod(startClass, startMeth, strArray);
                ...
            }
        }
        free(slashClassName);
        ...
    }
    

    AppRuntime继承自AndroidRuntime,通过调用runtime->start()会调用到AndroidRuntime的方法:
    首先, 通过startVm(&mJavaVM, &env, zygote)开启Android虚拟机;
    然后, 通过startReg(env)注册Android方法;
    最后, 通过className找到jclass和对应的main方法,调用ZygoteInit的main。

    3、startReg()

    struct RegJNIRec {
        int (*mProc)(JNIEnv*);
        const char* mName;
    };
    
    static const RegJNIRec gRegJNI[] = {
        REG_JNI(register_com_android_internal_os_RuntimeInit),
        REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
        REG_JNI(register_android_os_SystemClock),
        ...
    }
    
    int AndroidRuntime::startReg(JNIEnv* env){
        ...
        if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {}
        ...
        return 0;
    }
    
    static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env){
        for (size_t i = 0; i < count; i++) {
            // 执行mProc方法
            if (array[i].mProc(env) < 0) {
                ...
                return -1;
            }
        }
        return 0;
    }
    

    在startReg中会通过register_jni_procs遍历执行gRegJNI中注册的方法;其中gRegJNI是一个RegJNIRec的数组。

    zygote进程-java层

    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

    1、ZygoteInit.java->main()

    public static void main(String argv[]) {
        // 持有LocalServerSocket
        ZygoteServer zygoteServer = new ZygoteServer();
        ...
        final Runnable caller;
        try {
            ...
            // 解析参数,解析完毕后的值分别为
            // startSystemServer = true;
            // socketName = zygote;
            // enableLazyPreload = false;
            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            ...
            // 注册socket服务
            zygoteServer.registerServerSocketFromEnv(socketName);
            if (!enableLazyPreload) {
                ...
                // 预加载
                preload(bootTimingsTraceLog);
                ...
            } else {}
            // 进行一次gc
            gcAndFinalize();
            Zygote.nativeSecurityInit();
            Zygote.nativeUnmountStorageOnInit();
            ZygoteHooks.stopZygoteNoThreadCreation();
            // 启动system_server
            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;
                }
            }
            // 在zygote进程中轮询,不会在子进程中执行,因为上边已经return了
            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            ...
        } finally {
            // 轮询终止,关闭socket
            zygoteServer.closeServerSocket();
        }
        // 直接结束代码
        if (caller != null) {
            caller.run();
        }
    }
    

    在main中,做了如下操作:

    <1>解析传入的参数startSystemServer = true、enableLazyPreload = false
    <2>通过registerServerSocketFromEnv()注册socket服务
    <3>preload()预加载
    <4>gcAndFinalize()执行gc
    <5>fork子进程启动system_server
    <6>zygoteServer.runSelectLoop()开启轮询,等待client消息
    

    2、preload()

    static void preload(TimingsTraceLog bootTimingsTraceLog) {
        Log.d(TAG, "begin preload");
        bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
        beginIcuCachePinning();
        bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
        bootTimingsTraceLog.traceBegin("PreloadClasses");
        
        // 加载class
        preloadClasses();
        bootTimingsTraceLog.traceEnd(); // PreloadClasses
        bootTimingsTraceLog.traceBegin("PreloadResources");
    
        // 加载资源
        preloadResources();
        bootTimingsTraceLog.traceEnd(); // PreloadResources
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
        nativePreloadAppProcessHALs();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
    
        // 加载OpenGL
        preloadOpenGL();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        preloadSharedLibraries();
        preloadTextResources();
        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
        // for memory sharing purposes.
        WebViewFactory.prepareWebViewInZygote();
        endIcuCachePinning();
        warmUpJcaProviders();
        Log.d(TAG, "end preload");
        sPreloadComplete = true;
    }
    

    preload会提前加载Android系统类和系统资源(系统提供的布局等),简单分析一下preloadClasses

    3、preloadClasses()

    private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
    
    private static void preloadClasses() {
        InputStream is;
        try {
            is = new FileInputStream(PRELOADED_CLASSES);
        } catch () {}
        ...
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(is), 256);
            String line;
            while ((line = br.readLine()) != null) {
                ...
                try {
                    // 加载class
                    Class.forName(line, true, null);
                } catch () {}
            }
            ...
        } catch (IOException e) {} finally {}
    }
    

    其是这个方法就是读取PRELOADED_CLASSES路径下的文件,然后找到配置的类名,通过Class.forName()加载class。

    preloaded-classes

    展开全文
  • Android之Zygote和SystemServer启动过程

    千次阅读 2022-04-21 22:28:48
    先概述一下总体运行流程,当按电源键,首先是加载系统引导程序BootLoader,然后启动linux内核,再启动init进程,最后Zygote进程启动完成。理论上Android系统中的所有应用程序理论上都是由Zygote启动的。 init启动...
  • Zygote进程启动过程

    2022-05-13 13:57:41
    1.Zygote简介 在Android系统中,DVM(Dalvik虚拟机)、应用程序进程以及运行系统关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器。它通过fork(复制进程)的形式来创建应用程序进程和...
  • Android Zygote分析

    2021-02-22 21:50:50
    Android Zygote Android的zygote本质上是Android的虚拟机,是Android的SystemServer和几乎所有Java应用的卵化器,它们的父进程都是zygote。没有zygote就没有Android,Android的启动也离不开zygotezygote是很重要...
  • 1.4 深入理解Zygote

    2021-07-04 10:27:09
    zygote最初的名字叫“app_process”,这个名字是在Android.mk文件中被指定的,但app_process在运行过程中,通过Linux下的pctrl系统调用将自己的名字换成了“zygote”,所以我们通过ps命令看到的进程名是“zygote”。...
  • 三、zygote启动流程

    千次阅读 2022-04-23 16:56:53
    zygote被app_main.cpp里面的AppRuntime对象的start()方法启动之后做了以下事情 找到\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java打开main()函数在里面看到如下代码 1、创建ZygoteServer ...
  • 带着面试问题来看Zygote进程的启动 What:Zygote的作用是什么? How:Zygote的启动流程是什么? Why:Zygote的工作原理是什么? 1、Zygote进程的启动的作用: 主要是两大点:1.启动SystemServer(Android...
  • Zygote功能和Java部分主要方法源码解读
  • 深入Android系统(七)Zygote进程

    千次阅读 2020-11-14 12:14:29
    Zygote是Android中非常重要的一个进程,它和Init进程、SystemServer进程在Android中有着不可替代的地位。 Zygote简介 Linux的进程是通过系统调用fork产生的,fork出的子进程除了内核中的一些核心的数据结构和父进程...
  • 作者说这是一个系列的...Zygote 的中文意思是受精卵、合子,可以理解为孵化器——Android 中大多数应用进程和系统进程都是通过 Zygote 来生成的。 PS:源码基于 Android API 27。 Zygote 是怎么启动的? init ...
  • Android系统上的造物者——Zygote进程启动详解。
  • android 12 之zygote启动流程 1. 内核中的init启动 init进程在kernel启动流程图 (1)在rest_init函数中其实创建了两个重要内核线程init 和kthreadd,其PID分别为1和2 LINUX/android/kernel/msm-5.4/init/main.c ...
  • 这便是这篇文章的主角Zygote的主要职责。 本文所选Android系统版本是9.0 Pie,文中所有代码片段路径在代码块第一行已经标注。文章的目的是记录自己的学习历程与心得,不做商用或盈利,凡是学习过程中学习或引用过的...
  • zygote是受精卵的意思,它是Android中的一个非常重要的守护进程服务(Daem Service),所有的其他Dalvik虚拟机进程都是通过zygote孵化(fork)出来的。Android应用程序是由Java语言编写的,运行在各自独立的Dalvik...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,547
精华内容 9,818
关键字:

ZYGOTE