SystemServer进程的启动

​ 上一篇文章讲到System Server被fork出来之后,会去执行 com.android.server.SystemServer的main方法(源码目录:\frameworks\base\services\java\com\android\server\SystemServer.java),接下来就去看看这个main方法都干了什么事情。

SystemServer.java main方法

  public static void main(String[] args) {
        new SystemServer().run();
    }

    public SystemServer() {
        // Check for factory test mode.  检查工厂测试模式。 
        mFactoryTestMode = FactoryTest.getMode();//FactoryTest.getMode()具体返回啥不清楚,不过有个默认值:0

        // Record process start information. 记录进程启动信息
        // Note SYSPROP_START_COUNT will increment by *2* on a FDE device when it fully boots;
        // one for the password screen, second for the actual boot. 注意当FDE设备完全启动时,SYSPROP_START_COUNT将增加* 2 *。 一个用于密码屏幕,第二个用于实际启动。
        mStartCount = SystemProperties.getInt(SYSPROP_START_COUNT, 0) + 1;
        mRuntimeStartElapsedTime = SystemClock.elapsedRealtime();
        mRuntimeStartUptime = SystemClock.uptimeMillis();

        //重启
        mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
    }

总结

main方法很简单了,创建了一个SystemServer的对象,调用这个对象的run方法。SystemServer类在构造方法中,就是做一些检测及启动信息的保存等。

SystemServer.java run

private void run() {
        try {
            traceBeginAndSlog("InitBeforeStartServices");

            // Record the process start information in sys props. 
            // 记录进程启动信息,下面几个变量都是在构造方法里赋值的,应该是要写到某个文件吧
            SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));
            SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime));
            SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime));

            EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,
                    mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime);//日志

            //
            // Default the timezone property to GMT if not set. 如果未设置,则将时区属性默认为GMT。
            // 时区的获取
            String timezoneProperty = SystemProperties.get("persist.sys.timezone");
            // 获取的时区是否有效
            if (!isValidTimeZoneId(timezoneProperty)) {
                //获取的时区无效的话使用默认时区
                Slog.w(TAG, "persist.sys.timezone is not valid (" + timezoneProperty
                        + "); setting to GMT.");
                SystemProperties.set("persist.sys.timezone", "GMT");
            }

            // 语言获取
            // NOTE: Most changes made here will need an equivalent change to
            // core/jni/AndroidRuntime.cpp  
            //注意:此处所做的大多数更改都需要对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.forceSafeLabels();

            // Default to FULL within the system server.
            // 系统服务 中的默认值为FULL。
            SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;

            // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized
            // 停用SQLiteCompatibilityWalFlags,直到初始化设置提供程序
            SQLiteCompatibilityWalFlags.init(null);

            // Here we go! 终于开始了?
            Slog.i(TAG, "Entered the Android system server!"); 进入System Server
            int uptimeMillis = (int) SystemClock.elapsedRealtime();
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
            //这个 mRuntimeRestart 在构造方法赋值,主要是判断是不是重启
            if (!mRuntimeRestart) {
                MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
            }

            // 
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

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

            // 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.在系统服务内,应该对所有传入的Bundle进行隔离,以避免引发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.
            // 确保在系统中的binder调用总是在前台运行
            BinderInternal.disableBackgroundScheduling(true);

            // Increase the number of binder threads in system_server
            // 增加system_server中的binder线程数量  sMaxBinderThreads值是31
            BinderInternal.setMaxThreads(sMaxBinderThreads);

            // Prepare the main looper thread (this thread).
            // 设置main中 looper线程的一些属性,即当前线程
            android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            //看到熟悉的了。。哈哈哈,创建主线程looper
            Looper.prepareMainLooper();
            //日志相关吧
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

            // Initialize native services.
            // 初始化native层的服务,这里应该是加载某个so包
            System.loadLibrary("android_servers");

            // Debug builds - allow heap profiling. 调试版本-允许进行堆分析。
            if (Build.IS_DEBUGGABLE) { 
                initZygoteChildHeapProfiling();
            }

            // Debug builds - spawn a thread to monitor for fd leaks.调试版本-生成线程以监视fd泄漏。
            if (Build.IS_DEBUGGABLE) {
                spawnFdLeakCheckThread();
            }

            // 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.
            // 创建系统SystemServiceManager
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            //SystemServiceManager设置启动信息,都是时间信息
            mSystemServiceManager.setStartInfo(mRuntimeRestart,
                    mRuntimeStartElapsedTime, mRuntimeStartUptime);
            //把这个SystemServiceManager添加到LocalServices里面
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            // 准备线程池,没有接收???
            SystemServerInitThreadPool.get();
            // Attach JVMTI agent if this is a debuggable build and the system property is set.
            //如果这是可调试的构建,并且已设置系统属性,请附加JVMTI代理。
            if (Build.IS_DEBUGGABLE) {
                // Property is of the form "library_path=parameters".
                String jvmtiAgent = SystemProperties.get("persist.sys.dalvik.jvmtiagent");
                if (!jvmtiAgent.isEmpty()) {
                    int equalIndex = jvmtiAgent.indexOf('=');
                    String libraryPath = jvmtiAgent.substring(0, equalIndex);
                    String parameterList =
                            jvmtiAgent.substring(equalIndex + 1, jvmtiAgent.length());
                    // Attach the agent.
                    try {
                        Debug.attachJvmtiAgent(libraryPath, parameterList, null);
                    } catch (Exception e) {
                        Slog.e("System", "*************************************************");
                        Slog.e("System", "********** Failed to load jvmti plugin: " + jvmtiAgent);
                    }
                }
            }
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        // Start services. 启动service
        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);
            }
            //看起来 这个if用来监测系统启动快慢的
        }

        // Diagnostic to ensure that the system is in a base healthy state. Done here as a common
        // non-zygote process.
        // 诊断以确保系统处于基本正常状态。 在此作为常见的非zygote进程完成。
        if (!VMRuntime.hasBootImageSpaces()) {
            Slog.wtf(TAG, "Runtime is not running with a boot image!");
        }

        // Loop forever.
        //启动 主线程loop,哈哈哈,好熟悉
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

总结

System Server进程不愧是Android系统在Java世界的大管家,做的事情真多。哈哈哈哈,看一下主要做了什么。

  1. 记录启动的信息
  2. 时区设置
  3. 语言设置
  4. 确保在系统服务内,对所有传入的Bundle进行隔离。
  5. 确保在系统中的binder调用总是在前台运行
  6. 设置 stem_server中的binder线程数量值是31
  7. 创建stem_server进程中主线程的looper
  8. 调用 createSystemContext 创建系统上下文环境
  9. 创建SystemServiceManager的对象,设置创建时间,然后放入LocalServices里面
  10. 准备需要用的线程池,没有接收返回,应该相当于初始化
  11. 启动各种服务,包括:引导程序服务、核心服务、其他服务三大类
  12. 系统启动快慢监测
  13. 开启主线程的looper

上面13点是在SystemServer进程中主要做的事情,其中标红色的那几项是重中之重。下面先看一下createSystemContext方法

results matching ""

    No results matching ""