Android系統源碼分析--Zygote和SystemServer啓動過程

按計劃原本從這章開始寫四大組件的啓動過程的,可是看看源碼結構發現爲了說的更明白仍是先寫一點系統framework層啓動的內容,幫助理解四大組件的啓動以及管理過程。咱們知道四大組件管理是經過一些服務以及線程實現的,因此先把一些基本概念弄清楚比較好,好比AMS(ActivityManagerService)、PMS(PackageManagerService)等系統服務的做用以及調用方式,瞭解這些以後再看四大組件相對容易些,所以咱們本章先介紹系統啓動、部分系統服務的做用。java

Zygote啓動過程

Zygote是一個孕育器,Android系統全部的應用進程以及系統服務SystemServer都是有Zygote進程孕育(fork)而生的,所以Zygote在Android啓動過程當中起着決定做用。Zygote的啓動是從它的main函數開始的,所以咱們從這個函數開始分析。整個過程看下面的時序圖。android

Zygote.jpg
Zygote.jpg

下面咱們開始根據時序圖進行分析。git

Step 0.ZygoteInit.main緩存

public static void main(String argv[]) {
        ...
        try {
            ...

            registerZygoteSocket(socketName);

            ...

            preload();

            ...

            gcAndFinalize();

            ...

            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }

            runSelectLoop(abiList);

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            ...
        } catch (Throwable ex) {
            ...
        }
    }複製代碼

首先調用registerZygoteSocket方法,建立一個socket接口,用來和ActivityManagerService通信,而後調用preload方法預加載一些資源等;而後調用gcAndFinalize方法釋放一些內存;而後調用startSystemServer方法啓動SystemServer組件,而後調用runSelectLoop方法,建立一個無限循環,在socket接口上等待ActivityManagerService請求建立新的應用程序進程;最後調用closeServerSocket方法關閉上面建立的socket。微信

Step 1.ZygoteInit.registerZygoteSocketapp

private static void registerZygoteSocket(String socketName) {
        if (sServerSocket == null) {
            int fileDesc;
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                String env = System.getenv(fullSocketName);
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                ...
            }

            try {
                FileDescriptor fd = new FileDescriptor();
                fd.setInt$(fileDesc);
                sServerSocket = new LocalServerSocket(fd);
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }複製代碼

這個sServerSocket是經過傳入FileDescriptor(文件描述者)經過new一個來LocalServerSocket建立的。socket

Step 2.LocalServerSocket函數

public LocalServerSocket(FileDescriptor fd) throws IOException {
        impl = new LocalSocketImpl(fd);
        impl.listen(LISTEN_BACKLOG);
        localAddress = impl.getSockAddress();
    }複製代碼

在LocalServerSocket構造函數中又new了一個LocalSocketImpl,而後調用LocalSocketImpl的listen方法,最後經過getSockAddress方法獲取LocalSocketAddress對象。oop

Step 3.LocalSocketImpl源碼分析

/*package*/ LocalSocketImpl(FileDescriptor fd) throws IOException
    {
        this.fd = fd;
    }複製代碼

這裏只是傳入了FileDescriptor(文件描述者)。

Step 5.ZygoteInit.preload

static void preload() {
        ...
        beginIcuCachePinning();
        ...
        preloadClasses();
        ...
        preloadResources();
        ...
        preloadOpenGL();
        ...
        preloadSharedLibraries();
        preloadTextResources();
        ...
    }複製代碼

這裏主要是預加載,1.預加載ICU緩存,2.執行Zygote進程初始化,預加載一些普通類,3.預加載mResources,4.預加載OpenGL,5.預加載共享庫,6.預加載TextView的字體緩存。

Step 12.ZygoteInit.gcAndFinalize

/*package*/ static void gcAndFinalize() {
        final VMRuntime runtime = VMRuntime.getRuntime();
        ...
        System.gc();
        runtime.runFinalizationSync();
        System.gc();
    }複製代碼

這裏主要是調用System.gc來釋放一部份內存。

Step 13.ZygoteInit.startSystemServer

private static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException {
        ...

        int pid;

        try {
            ...

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            ...
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }複製代碼

首先Zygote會經過調用Zygote.forkSystemServer方法來建立一個新的進程來啓動SystemServer,而且返回這個進程的pid,若是pid爲0,而且有另一個Zygote則會執行waitForSecondaryZygote關閉另外的Zygote進程,而後調用handleSystemServerProcess方法。

Step 16.ZygoteInit.handleSystemServerProcess

private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller {

        closeServerSocket();

        ...

        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
            performSystemServerDexOpt(systemServerClasspath);
        }

        if (parsedArgs.invokeWith != null) {
            ...
        } else {
            ...
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }
    }複製代碼

首先調用closeServerSocket方法關閉socket,而後調用performSystemServerDexOpt來建立安裝鏈接InstallerConnection,最後調用RuntimeInit.zygoteInit方法。

Step 19.RuntimeInit.zygoteInit

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
        ...
        nativeZygoteInit();
        applicationInit(targetSdkVersion, argv, classLoader);
    }複製代碼

首先調用nativeZygoteInit函數來執行一個Binder進程間通信機制初始化工做,而後就能夠在進程間進行通信了,而後執行applicationInit方法。

Step 21.RuntimeInit.applicationInit

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
        ...
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }複製代碼

這裏主要是執行一個invokeStaticMain方法來調用SystemServer的main方法。

Step 24.ZygoteInit.runSelectLoop

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        while (true) {
            ...
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                ...
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    boolean done = peers.get(i).runOnce();
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }複製代碼

這裏經過acceptCommandPeer來建立ActivityManagerService與Socket的鏈接,而後調用ZygoteConnection.runOnce方法來建立新的應用程序。

SystemServer啓動過程

咱們從上面的Step 13 知道了SystemServer的main函數調用位置,下面咱們分析一下SystemServer的啓動過程。

SystemServer.jpg
SystemServer.jpg

在main方法中new了一個SystemServer而後調用它的run方法:

private void run() {
        try {
            ...

            // Mmmmmm... more memory!
            // 清除vm內存增加上限,因爲啓動過程須要較多的虛擬機內存空間
            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.
            // 設置內存的可能有效使用率爲0.8
            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.
            // 確保當前系統進程的binder調用,老是運行在前臺優先級(foreground priority)
            BinderInternal.disableBackgroundScheduling(true);

            // Increase the number of binder threads in system_server
            BinderInternal.setMaxThreads(sMaxBinderThreads);

            ...

            // 準備主線程的Looper
            Looper.prepareMainLooper();

            // Initialize native services.
            // 加載android_servers.so庫,該庫包含的源碼在frameworks/base/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添加到本地服務的成員sLocalServiceObjects
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        } finally {
            ...
        }

        // Start services.
        try {
            ...
            startBootstrapServices(); // 啓動引導服務
            startCoreServices();      // 啓動核心服務
            startOtherServices();     // 啓動其餘服務
        } catch (Throwable ex) {
            ...
        } finally {
            ...
        }

        ...

        // Loop(循環) forever.
        Looper.loop();
        ...
    }複製代碼

Step 3.Build.ensureFingerprintProperty

public static void ensureFingerprintProperty() {
        if (TextUtils.isEmpty(SystemProperties.get("ro.build.fingerprint"))) {
            try {
                SystemProperties.set("ro.build.fingerprint", FINGERPRINT);
            } catch (IllegalArgumentException e) {
                Slog.e(TAG, "Failed to set fingerprint property", e);
            }
        }
    }複製代碼

確認設備的指紋屬性。

Step 7.Looper.prepareMainLooper()

public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }複製代碼

準備main looper,這個詳細的過程咱們下一章再講,這裏先看一下流程。

Step 10.SystemServer.performPendingShutdown

private void performPendingShutdown() {
        final String shutdownAction = SystemProperties.get(
                ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
        if (shutdownAction != null && shutdownAction.length() > 0) {
            // 是否重啓
            boolean reboot = (shutdownAction.charAt(0) == '1');

            final String reason;
            if (shutdownAction.length() > 1) {
                reason = shutdownAction.substring(1, shutdownAction.length());
            } else {
                reason = null;
            }

            if (PowerManager.REBOOT_RECOVERY_UPDATE.equals(reason)) {
                File packageFile = new File(UNCRYPT_PACKAGE_FILE);
                if (packageFile.exists()) {
                    String filename = null;
                    try {
                        filename = FileUtils.readTextFile(packageFile, 0, null);
                    } catch (IOException e) {
                        Slog.e(TAG, "Error reading uncrypt package file", e);
                    }

                    if (filename != null && filename.startsWith("/data")) {
                        if (!new File(BLOCK_MAP_FILE).exists()) {
                            ...
                            return;
                        }
                    }
                }
            }
            ShutdownThread.rebootOrShutdown(null, reboot, reason);
        }
    }複製代碼

這裏主要是經過關機的action來判斷是否重啓或者關機。

Step 13.SystemServer.createSystemContext

private void createSystemContext() {
        // 初始化ActivityThread,並設置默認主題
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
    }複製代碼

首先調用ActivityThread.systemMain方法建立ActivityThread對象而後獲取mSystemContext,而且設置默認系統主題。

Step 15.ActivityThread.systemMain

public static ActivityThread systemMain() {
        ...
        ActivityThread thread = new ActivityThread();
        thread.attach(true);
        return thread;
    }複製代碼

建立ActivityThread對象,並調用attach方法。

Step 17.ResourcesManager.getInstance

public static ResourcesManager getInstance() {
        synchronized (ResourcesManager.class) {
            if (sResourcesManager == null) {
                sResourcesManager = new ResourcesManager();
            }
            return sResourcesManager;
        }複製代碼

單例模式建立ResourcesManager對象而且返回。

Step 19.ActivityThread.attach

private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ...
        } else {
            ...
            try {
                mInstrumentation = new Instrumentation();
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                ...
            }
        }

        ...
    }複製代碼

由於參數傳入的是true,代表是系統的線程,因此執行else裏面的內容,首先建立Instrumentation,而後調用ContextImpl.createAppContext方法建立ContextImpl,而後經過調用LoadedApk.makeApplication方法建立Application,而後調用Application.onCreate方法。

Step 22.ContextImpl.createAppContext

static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        return new ContextImpl(null, mainThread,
                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
    }複製代碼

經過new ContextImpl來建立ContextImpl對象。

Step 22.LoadedApk.makeApplication

public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
        ...

        Application app = null;

        ...

        try {
            ...
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ...
        }
        ...

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ...
            }
        }

        ...

        return app;
    }複製代碼

經過ContextImpl.createAppContext方法建立ContextImpl對象,而後調用mActivityThread.mInstrumentation.newApplication方法建立Application對象,而後調用instrumentation.callApplicationOnCreate方法。

Step 23.ContextImpl.createAppContext

static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        return new ContextImpl(null, mainThread,
                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
    }複製代碼

建立ContextImpl對象並返回。

Step 26.Instrumentation.createAppContext

public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return newApplication(cl.loadClass(className), context);
    }複製代碼

這裏主要是調用newApplication方法返回Application。

Step 28.Instrumentation.newApplication

static public Application newApplication(Class<?> clazz, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }複製代碼

調用class.newInstance方法建立Application,而後調用Application.attach方法,向Application中傳入context。

Step 32.Application.attach

/* package */ final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }複製代碼

經過ContextImpl.getImpl方法獲取LoadedApk對象。

Step 34.Instrumentation.callApplicationOnCreate

public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }複製代碼

這裏開始調用Application的onCreate方法。

Step 39.ActivityThread.getSystemContext

public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                mSystemContext = ContextImpl.createSystemContext(this);
            }
            return mSystemContext;
        }
    }複製代碼

經過ContextImpl.createSystemContext建立mSystemContext。

Step 40.ContextImpl.createSystemContext

static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread,
                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetrics());
        return context;
    }複製代碼

建立ContextImpl而且返回。

Step 43.SystemServer.startBootstrapServices

private void startBootstrapServices() {
        ...
        // 安裝服務
        Installer installer = mSystemServiceManager.startService(Installer.class);

        // Activity管理服務
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);

        ...
        // 電量管理服務
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

        ...

        // 管理LEDs和背光燈服務
        mSystemServiceManager.startService(LightsService.class);

        // 顯示管理服務
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

        // 包管理服務
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
        ...
        // 啓動用戶管理服務
        mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

        //初始化安裝包資源的屬性緩存
        AttributeCache.init(mSystemContext);

        // 啓動系統進程的應用實例
        mActivityManagerService.setSystemProcess();

        // 啓動傳感器服務
        startSensorService();
    }複製代碼

這裏主要是啓動系統引導服務。

Step 44.SystemServer.startCoreServices

private void startCoreServices() {
        // 啓動電池服務
        mSystemServiceManager.startService(BatteryService.class);

        // 啓動應用統計服務
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));

        // 啓動WebView更新服務
        mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
    }複製代碼

啓動核心服務。

Step 45.SystemServer.startOtherServices

這裏代碼就不貼了,都是啓動服務的代碼,這裏有不少服務,我簡單列一下服務並說一下服務基本功能。

服務 名稱 服務 名稱
SchedulingPolicyService CameraService
TelecomLoaderService AccountManagerService.Lifecycle
ContentService.Lifecycle VibratorService
ConsumerIrService AlarmManagerService
InputManagerService WindowManagerService
VrManagerService PersistentDataBlockService
MetricsLoggerService IpConnectivityMetrics
PinnerService InputMethodManagerService.Lifecycle
MountService.Lifecycle UiModeManagerService
LockSettingsService.Lifecycle BluetoothService
DeviceIdleController NsdService
StatusBarManagerService ClipboardService
NetworkManagementService WifiService
NetworkScoreService NetworkStatsService
NetworkPolicyManagerService WifiNanService
WifiP2pService TextServicesManagerService.Lifecycle
WifiScanningService ConnectivityService
RttService DevicePolicyManagerService.Lifecycle
UpdateLockService RecoverySystemService
NotificationManagerService DeviceStorageMonitorService
LocationManagerService CountryDetectorService
SearchManagerService.Lifecycle DropBoxManagerService
AudioService.Lifecycle DockObserver
ThermalObserver MidiService.Lifecycle
UsbService.Lifecycle SerialService
HardwarePropertiesManagerService NightDisplayService
JobSchedulerService SoundTriggerService
BackupManagerService.Lifecycle AppWidgetService
VoiceInteractionManagerService GestureLauncherService
SensorNotificationService ContextHubSystemService
DiskStatsService SamplingProfilerService
NetworkTimeUpdateService CommonTimeManagementService
EmergencyAffordanceService DreamManagerService
AssetAtlasService GraphicsStatsService
PrintManagerService RestrictionsManagerService
MediaSessionService HdmiControlService
TvInputManagerService MediaResourceMonitorService
TvRemoteService MediaRouterService
TrustManagerService FingerprintService
ShortcutService.Lifecycle LauncherAppsService
MediaProjectionManagerService WearBluetoothService
WearWifiMediatorService WearTimeService
MmsServiceBroker RetailDemoModeService
NsdService WallpaperManagerService.Lifecycle

參考:

Android系統啓動-SystemServer下篇
Android系統進程Zygote啓動過程的源代碼分析

原文地址:Android系統源碼分析--Zygote和SystemServer啓動過程

Android開發羣:192508518

微信公衆帳號:Code-MX

注:本文原創,轉載請註明出處,多謝。

相關文章
相關標籤/搜索