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世界的大管家,做的事情真多。哈哈哈哈,看一下主要做了什么。
- 记录启动的信息
- 时区设置
- 语言设置
- 确保在系统服务内,对所有传入的Bundle进行隔离。
- 确保在系统中的binder调用总是在前台运行
- 设置 stem_server中的binder线程数量值是31
- 创建stem_server进程中主线程的looper
- 调用 createSystemContext 创建系统上下文环境
- 创建SystemServiceManager的对象,设置创建时间,然后放入LocalServices里面
- 准备需要用的线程池,没有接收返回,应该相当于初始化
- 启动各种服务,包括:引导程序服务、核心服务、其他服务三大类
- 系统启动快慢监测
- 开启主线程的looper
上面13点是在SystemServer进程中主要做的事情,其中标红色的那几项是重中之重。下面先看一下createSystemContext方法