上篇说到Android系统的启动流程,Zygote
进程fork
的第一个进程就是SystemServer
进程。
这个进程负责启动和管理JavaFramework层
,也就是提供了框架层的很多服务,比如我们熟知的AMS,PMS,WMS,还有DisplayManagerService、CameraService
等等,也就是说它掌握了Android系统中的命脉,是Android系统中的大管家。
一起瞅瞅吧~
(本文源码基于Android9.0)
之前在Android系统的启动过程中?️说到,SystemServer
进程是由Zygote进程fork而来。
fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,可以理解为COPY了一个进程出来,而这个新进程就是它的子进程。
而关于SystemServer
的诞生,还要从ZygoteInit
的forkSystemServer
方法说起...(只保留主要代码)
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
//...
// 1
int pid;
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
/* For child process */
if (pid == 0) {
//2
zygoteServer.closeServerSocket();
//3
return handleSystemServerProcess(parsedArgs);
}
return true;
}
/**
* Finish remaining work for the newly forked system server process.
*/
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
//...
/*
* Pass the remaining arguments to SystemServer.
*/
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
//...
//4
RuntimeInit.commonInit();
//5
ZygoteInit.nativeZygoteInit();
//6
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
startSystemServer方法中:
forkSystemServer
方法创建了子进程——SystemServer进程
。fork
之后,这里判断了fork的返回值pid是否等于0,如果等于0,就代表fork成功,就处在SystemServer
进程中了。然后关闭了从Zygote进程fork带来的Socket对象。handleSystemServerProcess
方法,并最终走到zygoteInit
,做了一些新进程的初始化工作。zygoteInit方法中:
commonInit
方法就是做了一些进程通用的初始化工作,比如设置时区,重置log配置。nativeZygoteInit
方法通过JNI会走到native层,主要的工作就是创建了新的Binder线程池,这样SystemServer才能和各大app进程进行通信。applicationInit
方法,最终会走到findStaticMain
方法中,通过反射调用SystemServer类的main方法,简单贴下代码: protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
}
//...
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
}
//...
return new MethodAndArgsCaller(m, argv);
}
SystemServer进程
创建出来了,并且做了一些初始化工作,接下来就来到了main方法了,顾名思义,肯定要开始正经主要的工作了。
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
//...
// 1
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);
// 2
System.loadLibrary("android_servers");
// 3
performPendingShutdown();
// 4
createSystemContext();
// 5
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();
}
//...
// Start services.
try {
//6
startBootstrapServices();
//7
startCoreServices();
//8
startOtherServices();
SystemServerInitThreadPool.shutdown();
}
//...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
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
类,获取了上下文,并设置了一些系统主题。
SystemServiceManager
,用于后续的系统服务管理创建等工作。run方法最后的工作就是启动三个服务类型
的服务,也是我们重点关注的,分别是引导服务,核心服务,其他服务
。
这些服务一共有100多个,关系着Android整个应用生态,下面我们具体说下。
private void startBootstrapServices() {
//安装APK服务
traceBeginAndSlog("StartInstaller");
Installer installer = mSystemServiceManager.startService(Installer.class);
traceEnd();
//AMS,负责四大组件的启动调度等工作
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
traceEnd();
// 管理和显示背光LED等服务
traceBeginAndSlog("StartLightsService");
mSystemServiceManager.startService(LightsService.class);
traceEnd();
//PMS,负责APK安装,解析卸载等工作
traceBeginAndSlog("StartPackageManagerService");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
traceEnd();
//...
}
引导服务中,有几个我们毕竟熟悉的,比如AMS、PMS。
private void startCoreServices() {
traceBeginAndSlog("StartBatteryService");
// 管理电池相关服务
mSystemServiceManager.startService(BatteryService.class);
traceEnd();
// 收集用户使用时长服务
traceBeginAndSlog("StartUsageService");
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
traceEnd();
// Webview更新服务
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
traceBeginAndSlog("StartWebViewUpdateService");
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
traceEnd();
}
//...
}
private void startOtherServices() {
//...
//电话管理服务
traceBeginAndSlog("StartTelephonyRegistry");
telephonyRegistry = new TelephonyRegistry(context);
ServiceManager.addService("telephony.registry", telephonyRegistry);
traceEnd();
//WMS,窗口管理服务,也是打交道比较多的
traceBeginAndSlog("StartWindowManagerService");
ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
mSensorServiceStart = null;
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
traceEnd();
//输入事件管理服务
traceBeginAndSlog("StartInputManager");
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
traceEnd();
//...
}
启动了这么多服务,我们再看一下服务都是怎么具体启动的:
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
// Create the service.
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} //...
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
// 所有系统服务的集合
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
可以看到,首先通过反射创建了对应的Service类,然后把对应的Service加入到mServices集合中,完成注册。然后调用onStart方法启动对应的Service,完成初始化工作。
到这里,SystemServer
的启动工作就完成了,再来回顾下,这个过程,到底干了些啥?
首先
,Zygote fork了SystemServer
这个子进程,然后关闭了原有的socket
,创建了新的Binder
线程池。其次
,做了一些初始化工作,创建了Context对象,创建了SystemServiceManager类,用于管理所有的系统服务。最后
,启动了三类系统服务,分别是引导服务,核心服务和其他服务。我们注意到,在SystemServer
被fork出来之后,做了一个操作就是关闭了Sokcet
,启动了Binder
线程池用于进程间通信。问题来了,为啥Zygote进程是用Socket通信,而SystemServer
进程是用Binder进行通信呢?
其实这是两个问题,第一个问题是问为什么Android
获取系统服务是用的Binder进程通信呢?
这就涉及到Binder
的知识点了,Binder
之所以被设计出来,就是因为它有区别于其他IPC方式的两大优点:
第二个问题就是,为什么Zygote进程不用Binder而用Socket通信呢?这也是wanAndroid
中的一个问题:
每日一问 | Activity启动流程中,大部分都是用Binder通讯,为啥跟Zygote通信的时候要用socket呢?(https://www.wanandroid.com/wenda/show/10482)
评论区主要有以下观点:
ServiceManager
不能保证在zygote起来的时候已经初始化好,所以无法使用Binder。Socket
的所有者是 root,只有系统权限用户才能读写,多了安全保障。Binder
工作依赖于多线程,但是fork的时候是不允许存在多线程的,多线程情况下进程fork容易造成死锁,所以就不用Binder了。Binder线程池到底是什么?之前有读者也问过类似的问题。
Binder线程池
位于服务端,它的主要作用就是将每个业务模块的Binder请求统一转发到远程Servie中去执行,从而避免了重复创建Service的过程。也就是服务端只有一个,但是可以处理多个不同客户端的Binder请求。在SystemServer进程启动的过程中,也启动了很多系统服务,其中就包括和应用交互比较多的三个服务:
AMS
,ActivityManagerService,负责四大组件的启动,切换,调度工作。PMS
,PackageManagerService,负责APK的安装,解析,卸载工作。WMS
,WindowManagerService,负责窗口启动,添加,删除等工作。