赞
踩
SystemServer 是 Android 系统 Java 层最重要的进程之一,几乎所有的 Java 层 Binder 服务都运行在这个进程里。
SystemServer 的启动大致可分为两个阶段:
上一节我们分析了第一阶段,今天我们来分析第二阶段:
public static void main(String[] args) {
//new 一个SystemServer对象,再调用该对象的run()方法
new SystemServer().run();
}
main 函数由 zygote 进程 fork 后运行,作用是 new 一个 SystemServer 对象,再调用该对象的 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); // 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", ""); } // Binder、Sqlite相关属性设置 // 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. SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL; // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized SQLiteCompatibilityWalFlags.init(null); // Here 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 的初始化 Looper.prepareMainLooper(); Looper.getMainLooper().setSlowLogThresholdMs( SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS); // 加载 libandroid_services.so // Initialize native services. System.loadLibrary("android_servers"); // Debug builds - allow heap profiling. if (Build.IS_DEBUGGABLE) { initZygoteChildHeapProfiling(); } // 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 } // System Server 的启动阶段 // 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); } } // Diagnostic to ensure that the system is in a base healthy state. Done here as a common // non-zygote process. if (!VMRuntime.hasBootImageSpaces()) { Slog.wtf(TAG, "Runtime is not running with a boot image!"); } // Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
主要分为两个阶段:
一 SystemServer 启动前的准备阶段工作
系统时间、时区、语言的设置
虚拟机运行库、内存参数、内存利用率的调整
设置当前线程的优先级
加载 libandroid_services.so 库
初始化 Looper
SystemContext 与 SystemServiceManager 的初始化
二 SystemServer 启动
执行 startBootstrapServices、startCoreServices、startOtherServices 启动所有的系统服务
调用 Looper.loop() 循环处理消息
接下来我们来分析 createSystemContext() 方法的执行过程:
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
接着看看 ActivityThread.systemMain() 的具体实现:
public static ActivityThread systemMain() {
ThreadedRenderer.initForSystemProcess();
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
创建了一个 ActivityThread 对象,然后调用 ActivityThread 对象的 attach 方法。
ActivityThread 是应用程序的主线程类,启动应用最后执行到的就是 ActivityThread 的 main() 方法。那么为什么 SystemServer 要初始化一个 ActivityThread 对象?
实际上 SystemServer 不仅仅是一个单纯的后台进程,它也是一个运行着 Service 组件的进程,很多系统对话框就是从 SystemServer 中显示出来的,因此 SystemServer 本身也需要一个和 APK 应用类似的上下文环境,创建 ActivityThread 是获取这个环境的第一步。
ActivityThread 在 SystemServer 进程中与普通进程还是有区别的,这里主要是通过 attach(boolen system,int seq) 方法的参数 system 来标识,函数如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。