三、zygote启动流程

zygote被app_main.cpp里面的AppRuntime对象的start()方法启动之后做了以下事情

在\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java打开main()函数在里面看到如下代码

1、创建ZygoteServer,此对象里面有一个核心函数runSelectLoop()实现了socket通信,新APP的启动就是靠这个socket通知zygote

 ZygoteServer zygoteServer = new ZygoteServer();

2、提前加载类,加载系统资源,加载其它

// 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
}

preload()方法代码:

static void preload(TimingsTraceLog bootTimingsTraceLog) {
        preloadClasses();
        
        preloadResources();
        
        nativePreloadAppProcessHALs();   
        preloadOpenGL();
       
        preloadSharedLibraries();
        preloadTextResources(); 
}

3、启动SystemServer

if (startSystemServer) {
     Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
     if (r != null) {
         r.run();//通过反射机制执行SystemServer.java的main()函数
         return;
     }
}

注:SystemServer被启动之后,所有的其它系统服务都由SystemServer创建,文件路径:frameworks\base\services\java\com\android\server\SystemServer.java,打开文件找到run()函数如下

private void run() {
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }
        // 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.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

        traceBeginAndSlog("StartServices");
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
        Looper.loop();
}
启动其它服务的startOtherServices()代码如下。如果需要启动自己的服务,可以放在该函数里面启动
private void startOtherServices() {
        mSystemServiceManager.startService(KeyChainSystemService.class);
        mSystemServiceManager.startService(TelecomLoaderService.class);
        mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
        mSystemServiceManager.startService(CONTENT_SERVICE_CLASS);
        mSystemServiceManager.startService(DropBoxManagerService.class);
        mSystemServiceManager.startService(VrManagerService.class);
        mSystemServiceManager.startService(BluetoothService.class);
        mSystemServiceManager.startService(IpConnectivityMetrics.class);
        mSystemServiceManager.startService(NetworkWatchlistService.Lifecycle.class);
        mSystemServiceManager.startService(PinnerService.class);
        mSystemServiceManager.startService(InputMethodManagerService.Lifecycle.class);
        mSystemServiceManager.startService(STORAGE_MANAGER_SERVICE_CLASS);
        mSystemServiceManager.startService(STORAGE_STATS_SERVICE_CLASS);
        mSystemServiceManager.startService(UiModeManagerService.class);
        mSystemServiceManager.startService(LOCK_SETTINGS_SERVICE_CLASS);
        mSystemServiceManager.startService(PersistentDataBlockService.class);
        mSystemServiceManager.startService(OemLockService.class);
        mSystemServiceManager.startService(DeviceIdleController.class);
        mSystemServiceManager.startService(DevicePolicyManagerService.Lifecycle.class);
        mSystemServiceManager.startService(ClipboardService.class);
        mSystemServiceManager.startService(TextServicesManagerService.Lifecycle.class);
        mSystemServiceManager.startService(TextClassificationManagerService.Lifecycle.class);
        mSystemServiceManager.startService(NetworkScoreService.Lifecycle.class);
        mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
        mSystemServiceManager.startService("com.android.server.wifi.scanner.WifiScanningService");
        mSystemServiceManager.startService("com.android.server.wifi.rtt.RttService");
        mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);
        mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
        mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS);
        mSystemServiceManager.startService(DeviceStorageMonitorService.class);
        mSystemServiceManager.startService(SEARCH_MANAGER_SERVICE_CLASS);
        mSystemServiceManager.startService(WALLPAPER_SERVICE_CLASS);
        mSystemServiceManager.startService(AudioService.Lifecycle.class);
        mSystemServiceManager.startService(BroadcastRadioService.class);
        mSystemServiceManager.startService(DockObserver.class);
        mSystemServiceManager.startService(THERMAL_OBSERVER_CLASS);
        mSystemServiceManager.startService(MIDI_SERVICE_CLASS);
        mSystemServiceManager.startService(USB_SERVICE_CLASS);
        mSystemServiceManager.startService(TwilightService.class);
        mSystemServiceManager.startService(ColorDisplayService.class);
        mSystemServiceManager.startService(JobSchedulerService.class);
        mSystemServiceManager.startService(SoundTriggerService.class);
        mSystemServiceManager.startService(TrustManagerService.class);
        mSystemServiceManager.startService(BACKUP_MANAGER_SERVICE_CLASS);
        mSystemServiceManager.startService(APPWIDGET_SERVICE_CLASS);
        mSystemServiceManager.startService(VOICE_RECOGNITION_MANAGER_SERVICE_CLASS);
        mSystemServiceManager.startService(GestureLauncherService.class);
        mSystemServiceManager.startService(SensorNotificationService.class);
        mSystemServiceManager.startService(ContextHubSystemService.class);
        mSystemServiceManager.startService(TIME_ZONE_RULES_MANAGER_SERVICE_CLASS);
        mSystemServiceManager.startService(EmergencyAffordanceService.class);
        mSystemServiceManager.startService(DreamManagerService.class);
        mSystemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);
        mSystemServiceManager.startService(COMPANION_DEVICE_MANAGER_SERVICE_CLASS);
        mSystemServiceManager.startService(RestrictionsManagerService.class);
        mSystemServiceManager.startService(MediaSessionService.class);
        mSystemServiceManager.startService(MediaUpdateService.class);
        mSystemServiceManager.startService(HdmiControlService.class);
        mSystemServiceManager.startService(TvInputManagerService.class);
        mSystemServiceManager.startService(MediaResourceMonitorService.class);
        mSystemServiceManager.startService(TvRemoteService.class);
        mSystemServiceManager.startService(FingerprintService.class);
        mSystemServiceManager.startService(ShortcutService.Lifecycle.class);
        mSystemServiceManager.startService(LauncherAppsService.class);
        mSystemServiceManager.startService(CrossProfileAppsService.class);
        mSystemServiceManager.startService(MediaProjectionManagerService.class);
        mSystemServiceManager.startService(WEAR_CONFIG_SERVICE_CLASS);
        mSystemServiceManager.startService(WEAR_CONNECTIVITY_SERVICE_CLASS);
        mSystemServiceManager.startService(WEAR_DISPLAY_SERVICE_CLASS);
        mSystemServiceManager.startService(WEAR_TIME_SERVICE_CLASS);
        mSystemServiceManager.startService(WEAR_LEFTY_SERVICE_CLASS);
        mSystemServiceManager.startService(WEAR_GLOBAL_ACTIONS_SERVICE_CLASS);
        mSystemServiceManager.startService(SLICE_MANAGER_SERVICE_CLASS);
        mSystemServiceManager.startService(CameraServiceProxy.class);
        mSystemServiceManager.startService(IOT_SERVICE_CLASS);
        mSystemServiceManager.startService(StatsCompanionService.Lifecycle.class);
        mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);
        mSystemServiceManager.startService(AUTO_FILL_MANAGER_SERVICE_CLASS);
        mSystemServiceManager.startService(className);
    }

4、调用runSelectLoop()

// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
caller = zygoteServer.runSelectLoop(abiList);

runSelectLoop()的具体实现在frameworks\base\core\java\com\android\internal\os\ZygoteServer.java里面

当有新的APP需要启动时, 调用processOneCommand()取到新的请求数据

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;
            }
                Os.poll(pollFds, -1);
            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) {

                            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;
                        }
                    } finally {
                        mIsForkChild = false;
                    }
                }
            }
        }
    }

processOneCommand() 实现在frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java

 Runnable processOneCommand(ZygoteServer zygoteServer) {
        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;

        try {
            args = readArgumentList();//读取消息
            descriptors = mSocket.getAncillaryFileDescriptors();
        } catch (IOException ex) {
            throw new IllegalStateException("IOException on command socket", ex);
        }

        // readArgumentList returns null only when it has reached EOF with no available
        // data to read. This will only happen when the remote socket has disconnected.
        if (args == null) {
            isEof = true;
            return null;
        }

        int pid = -1;
        FileDescriptor childPipeFd = null;
        FileDescriptor serverPipeFd = null;

        parsedArgs = new Arguments(args);

        if (parsedArgs.abiListQuery) {
            handleAbiListQuery();
            return null;
        }

        if (parsedArgs.preloadDefault) {
            handlePreload();
            return null;
        }

        if (parsedArgs.preloadPackage != null) {
            handlePreloadPackage(parsedArgs.preloadPackage, parsedArgs.preloadPackageLibs,
                    parsedArgs.preloadPackageLibFileName, parsedArgs.preloadPackageCacheKey);
            return null;
        }

        if (parsedArgs.apiBlacklistExemptions != null) {
            handleApiBlacklistExemptions(parsedArgs.apiBlacklistExemptions);
            return null;
        }

        if (parsedArgs.hiddenApiAccessLogSampleRate != -1) {
            handleHiddenApiAccessLogSampleRate(parsedArgs.hiddenApiAccessLogSampleRate);
            return null;
        }

        if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
            throw new ZygoteSecurityException("Client may not specify capabilities: " +
                    "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
                    ", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
        }

        applyUidSecurityPolicy(parsedArgs, peer);
        applyInvokeWithSecurityPolicy(parsedArgs, peer);

        applyDebuggerSystemProperty(parsedArgs);
        applyInvokeWithSystemProperty(parsedArgs);

        int[][] rlimits = null;

        if (parsedArgs.rlimits != null) {
            rlimits = parsedArgs.rlimits.toArray(intArray2d);
        }

        int[] fdsToIgnore = null;

        if (parsedArgs.invokeWith != null) {
            try {
                FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                childPipeFd = pipeFds[1];
                serverPipeFd = pipeFds[0];
                Os.fcntlInt(childPipeFd, F_SETFD, 0);
                fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
            } catch (ErrnoException errnoEx) {
                throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx);
            }
        }

        /**
         * In order to avoid leaking descriptors to the Zygote child,
         * the native code must close the two Zygote socket descriptors
         * in the child process before it switches from Zygote-root to
         * the UID and privileges of the application being launched.
         *
         * In order to avoid "bad file descriptor" errors when the
         * two LocalSocket objects are closed, the Posix file
         * descriptors are released via a dup2() call which closes
         * the socket and substitutes an open descriptor to /dev/null.
         */

        int [] fdsToClose = { -1, -1 };

        FileDescriptor fd = mSocket.getFileDescriptor();

        if (fd != null) {
            fdsToClose[0] = fd.getInt$();
        }

        fd = zygoteServer.getServerSocketFileDescriptor();

        if (fd != null) {
            fdsToClose[1] = fd.getInt$();
        }

        fd = null;

		//根据读取到的消息创建一个进程
        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);
        }
    }

创建一个新APP的关键代码

pid = Zygote.forkAndSpecialize();

至此,一个新的APP被创建出来

大爷,赏个铜板呗

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑三少_Creat

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值