美文网首页
Android系统之System Server

Android系统之System Server

作者: 棒棒0_0 | 来源:发表于2020-05-17 17:38 被阅读0次

System Server是android基本服务的提供者,是android系统运行的最基本需求,所有server运行在一个叫system_process的进程中。system_process进程是android java虚拟机启动的第一个进程。可以说,整个android系统的业务都是围绕system server而展开。所以,当system_process死掉后,系统必须重启。

1.System Server启动的入口

在System Server中,首先调用main()。然后调用了SystemServer().run()。

    private void run() {
        try {
            traceBeginAndSlog("InitBeforeStartServices");
            // If a device's clock is before 1970 (before 0), a lot of
            // APIs crash dealing with negative numbers, notably
            // java.io.File#setLastModified, so instead we fake it and
            // hope that time from cell towers or NTP fixes it shortly.
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }

            //
            // Default the timezone property to GMT if not set.
            //
            String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
            if (timezoneProperty == null || timezoneProperty.isEmpty()) {
                Slog.w(TAG, "Timezone not set; setting to GMT.");
                SystemProperties.set("persist.sys.timezone", "GMT");
            }

            // If the system has "persist.sys.language" and friends set, replace them with
            // "persist.sys.locale". Note that the default locale at this point is calculated
            // using the "-Duser.locale" command line flag. That flag is usually populated by
            // AndroidRuntime using the same set of system properties, but only the system_server
            // and system apps are allowed to set them.
            //
            // NOTE: Most changes made here will need an equivalent change to
            // core/jni/AndroidRuntime.cpp
            if (!SystemProperties.get("persist.sys.language").isEmpty()) {
                final String languageTag = Locale.getDefault().toLanguageTag();

                SystemProperties.set("persist.sys.locale", languageTag);
                SystemProperties.set("persist.sys.language", "");
                SystemProperties.set("persist.sys.country", "");
                SystemProperties.set("persist.sys.localevar", "");
            }

            // The system server should never make non-oneway calls
            Binder.setWarnOnBlocking(true);
            // The system server should always load safe labels
            PackageItemInfo.setForceSafeLabels(true);
            // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized
            SQLiteCompatibilityWalFlags.init(null);

            // Here we go!
            Slog.i(TAG, "Entered the Android system server!");
            int uptimeMillis = (int) SystemClock.elapsedRealtime();
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
            if (!mRuntimeRestart) {
                MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
            }

            // In case the runtime switched since last boot (such as when
            // the old runtime was removed in an OTA), set the system
            // property so that it is in sync. We can | xq oqi't do this in
            // libnativehelper's JniInvocation::Init code where we already
            // had to fallback to a different runtime because it is
            // running as root and we need to be the system user to set
            // the property. http://b/11463182
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

            // Mmmmmm... more memory!
            VMRuntime.getRuntime().clearGrowthLimit();

            // The system server has to run all of the time, so it needs to be
            // as efficient as possible with its memory usage.
            VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

            // Some devices rely on runtime fingerprint generation, so make sure
            // we've defined it before booting further.
            Build.ensureFingerprintProperty();

            // Within the system server, it is an error to access Environment paths without
            // explicitly specifying a user.
            Environment.setUserRequired(true);

            // Within the system server, any incoming Bundles should be defused
            // to avoid throwing BadParcelableException.
            BaseBundle.setShouldDefuse(true);

            // Within the system server, when parceling exceptions, include the stack trace
            Parcel.setStackTraceParceling(true);

            // Ensure binder calls into the system always run at foreground priority.
            BinderInternal.disableBackgroundScheduling(true);

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

            // Prepare the main looper thread (this thread).
            android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            Looper.prepareMainLooper();
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

            // 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);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }

        StrictMode.initVmDefaults(null);

        if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
            int uptimeMillis = (int) SystemClock.elapsedRealtime();
            MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
            final int MAX_UPTIME_MILLIS = 60 * 1000;
            if (uptimeMillis > MAX_UPTIME_MILLIS) {
                Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                        "SystemServer init took too long. uptimeMillis=" + uptimeMillis);
            }
        }

        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

在上述代码中,首先创建了一个system context,这个对象在整个system server中使用非常频繁。接着创建了一个SystemServiceManager实例。顾名思义,SystemServiceManager就是SystemService的管理者,管理所有的SystemService。代码中把接着SystemServiceManager的实例通过LocalServices.addService()语句设置到LocalServices中。LocalService的功能类似于SystemServiceManager,不同点在于LocalService专门用来管理system_process
进程中的SystemService,也就没有真正的跨进程通信,所以也就没有Binder 对象。

2.System Server的启动过程

接着就是启动各种系统服务,在这里分三种类型的SystemService依次启动,对应三种方法。

   startBootstrapServices();
   startCoreServices();
   startOtherServices();

这三种方法的顺序不能混乱,一定要按照上述顺序依次执行。通过查看代码,我们发现在startBootstrapServices()中启动的Service为:
Installer
DeviceIdentifiersPolicyService
ActivityManagerService.Lifecycle.class
PowerManagerService
RecoverySystemService
LightsService
DisplayManagerService
UserManagerService
OverlayManagerService
启动这些SystemService都是通过SystemServiceManager.startService()的方式启动。启动完成后会调用SystemService的onStart()方法。
在startCoreServices()中启动的Service为:
BatteryService
UsageStatsService
WebViewUpdateService
接着就是调用startOtherServices()。在startOtherServices()中启动的service非常多。这些service不一定全部都启动,系统会依照一些配置,选择性启动某些服务。

3.三种不同的启动服务的方式

在以上的启动服务中,我们发现了三种启动方式。
第一种:

LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

第二种:

mSystemServiceManager.startService(LightsService.class);

第三种:

ServiceManager.addService("vibrator", vibrator);

这三种方式有什么不同呢?
1.类型不同
SystemServiceManager.startService()和LocalServices.addService()启动的系统服务是SystemService的子类,启动这些服务后会回调SystemService的onStart()方法。ServiceManager.addService()启动的系统服务是实现了Android IPC 的Binder的子类,这些服务启动后会调用systemReady()或systemRunning()方法。
2.SystemServiceManager.startService()和ServiceManager.addService()中启动的服务需要Binder对象,而LocalServices.addService()却没有Binder对象
3.SystemServiceManager.startService()中启动的是需要关心lifecycle events的服务,而ServiceManager.addService()和LocalServices.addService()不关心lifecycle events
4.ServiceManager.addService()启动的服务本身是实现Binder通信的子类,而一般SystemServiceManager.startService()启动的服务是某个服务的内部类且这个内部类是SystemService的子类,如BackupManagerService$Lifecycle,在启动这个Lifecycle的内部类服务时,当回调onStart()方法时通过SystemService的publishBinderService()方法应用某个服务的Binder对象,且这个Binder的实现类也是某个服务的内部类。也就是说需要启动服务,而这个服务需要关心lifecycle events,所以不能通过ServiceManager.addService()的方式启动,然后在这个服务中声明一个实现了SystemService的子类Lifecycle,来接受lifecycle events,通过SystemServiceManager.startService()的方式启动这个服务,在SystemService的回调方法onStart()中应用这个服务的Binder对象。所以通过SystemServiceManager.startService()启动的服务,实际是启动了一个即需要关心lifecycle events,也需要像ServiceManager.addService()那样需要Binder对象的服务。

相关文章

网友评论

      本文标题:Android系统之System Server

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