SystemServer简介
SystemServer是Zygote孵化出来的一个核心进程。主要负责管理Android系统中核心服务。为了防止应用进程对系统造成破坏,应用进程没有权限直接访问设备的底层资源,只能通过SystemService中的服务代理访问,并且通过Binder的形式。
SystemServer的启动
SystemServer的启动分成两部分,一部分是Zygote进程Fork出SystemServer进程,另一部分是SystemServer类的main函数来初始化系统服务。前面已经介绍过在Init进程中设置了启动参数,Zygote进程去解析并Fork出SystemServer进程。这块主要介绍第二部分。
源码目录:/frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
try {
// 设置时钟
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
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");
// 设置Dalvik属性
SystemProperties.set("persist.sys.dalvik.vm.lib.2",
VMRuntime.getRuntime().vmLibrary());
VMRuntime.getRuntime().clearGrowthLimit();
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
//设置Binder线程
BinderInternal.setMaxThreads(sMaxBinderThreads);
//初始化Looper.
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);
//装载库libandroid.
System.loadLibrary("android_servers");
//获取Context
createSystemContext();
//创建SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//初始化线程池
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
//启动核心服务,如AMS
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();
}
//开启Looper.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
main方法主要工作如下:
(1)设置属性persist.sys.dalvik.vm.lib.2的值为当前虚拟机的运行库路径。
(2)调整时间。如果系统时间比1970还早,调整到1970年。
(3)调整虚拟机堆的内存。设定虚拟机堆利用率为0.8,当实际的使用率偏离设定的比率时,虚拟机在垃圾回收的时候将调整堆的大小,使实际使用率接近设定的百分比。
(4)装载库libandroid servers.so。这个库的源文件位于目录frameworks/base/services/jni下。
(5)调用nativeInit()方法初始化native层的Binder服务。
(6)调用createSystemContext()来获取Context。此方法核心逻辑还有创建ActivityThread,这个是应用进程的入口,尤其是APP进程,
因为在SystemServer进程中,不单单是一个系统进程,也创建了应用环境,运行了一些Service,类似于系统的一些弹窗,Toast都会在这处理。ActivityThread.systemMain方法中的attach有flag判断是系统进程还是应用进程,此处会判断为系统进程,并且Load系统中的一个应用,叫framework-res.apk,所以此方法主要是为了创建应用环境
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);
}
(7)创建SystemServiceManager的对象mSystemServiceManager。这个对象负责系统Service的启动。
(8)调用startBootstrapServices()方法、startCoreServices()方法和startOtherServices()创建并运行所有Java服务。
(9)调用Loop.loop(),进入处理消息的循环。
SystemServer进程中的WatchDog
SystemServer中有个检测机制,就是WatchDog。因为SystemServer在Android系统是个复杂的进程,里面运行的服务超过五十多个,爆出问题风险比较大。所以采用WatchDog的形式监控SystemServer进程,如果出现异常会杀死SystemServer进程,Zygote就会收到SystemServer进程的死亡信号,Zygote也会杀死自己,Init进程收到Zygote的死亡信号,Init进程杀死所有子进程并重启Zygote,手机就会出现重启,这种软起动速度会更快,降低对用户的影响。首先,WatchDog是以单例模式运行。
final Watchdog watchdog = Watchdog.getInstance();
watchdog.init(context, mActivityManagerService);
通过创建HandlerChecker
对象(本质是Runable),搭配Handler,在构造时就和对应线程相互关联,对应的是被检测的线程,并且使用数组列表存放。
private Watchdog() {
super("watchdog");
mMonitorChecker = new HandlerChecker(FgThread.getHandler(),
"foreground thread", DEFAULT_TIMEOUT);
mHandlerCheckers.add(mMonitorChecker);
// Add checker for main thread. We only do a quick check since there
mHandlerCheckers.add(new HandlerChecker(new Handler(Looper.getMainLooper()),
"main thread", DEFAULT_TIMEOUT));
// Add checker for shared UI thread.
mHandlerCheckers.add(new HandlerChecker(UiThread.getHandler(),
"ui thread", DEFAULT_TIMEOUT));
// And also check IO thread.
mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(),
"i/o thread", DEFAULT_TIMEOUT));
// And the display thread.
mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(),
"display thread", DEFAULT_TIMEOUT));
}
初始化中添加了5个公共线程,主线程,FgThread,UiThread,IoThread,DisplayThread
,区别不大,只是优先级不一样,也注册了重启广播:
public void init(Context context, ActivityManagerService activity) {
mResolver = context.getContentResolver();
mActivity = activity;
context.registerReceiver(new RebootRequestReceiver(),
new IntentFilter(Intent.ACTION_REBOOT),
android.Manifest.permission.REBOOT, null);
}
对线程的监控
对线程使用addThread方法创建与线程关联的HandlerChecker。
328 public void addThread(Handler thread, long timeoutMillis) {
329 synchronized (this) {
330 if (isAlive()) {
331 throw new RuntimeException("Threads can't be added once the Watchdog is running");
332 }
333 final String name = thread.getLooper().getThread().getName();
334 mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis));
335 }
336 }
对服务的监控
对服务使用addMonitor方法来创建与服务关联的HandlerChecker,前提是服务需要继承Monitor接口。像AMS,WMS,IMS等都实现了此接口。
315 public void addMonitor(Monitor monitor) {
316 synchronized (this) {
317 if (isAlive()) {
318 throw new RuntimeException("Monitors can't be added once the Watchdog is running");
319 }
320 mMonitorChecker.addMonitor(monitor);
321 }
322 }
监控原理
检测原理其实很简单,就是给监控线程发消息,并确认回复。如果发送的消息不能在规定的时间得到处理,就表明线程被不正常的占用了。PS:使用Handler监听主线程慢函数或许是从这里得到的灵感。
- 给所有受控线程发消息。
- 发完消息后,调用wait方法,WatchDog睡眠一段时间。
- 逐个检查是否有线程出问题,如果有,立马杀死进程。 核心逻辑在第三步,对监控线程的状态检查分成4个等级
- COMPLETED:值为0,表示状态良好。
- WAITING:值为1,表示正在等待消息处理的结果。
- WAITED_HALF:值为2,表示等待时间已经超出规定时间的一半。
- OVERDUE:值为3,表示已经超出规定的时间。
所有最终,只要是OVERDUE就会杀死进程。
源码好无聊,有兴趣自己去看吧,说了那么多,面试的时候你知道该怎么吹了吧......