上一篇我们分析了zygote进程的启动过程,其中有一个步骤是startSystemServer,这一篇就来详细分析一下system_server进程的启动过程。
1 Zygote中startSystemServer
frameworks/base/core/java/com/android/internal/os/ZygoteInit
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
...
/* For child process */
/**
* 在子进程中启动systemServer进程
*/
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
handleSystemServerProcess(parsedArgs);
}
return true;
}
上面通过handleSystemServerProcess来启动应用程序进程,源码如下:
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
if (parsedArgs.invokeWith != null) {
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createSystemServerClassLoader(systemServerClasspath,
parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
首先关闭了从zygote进复制的无用的socket, 然后在handleSystemServerProcess的最后调用了RuntimeInit.zygoteInit方法,我们跟进去看:
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
redirectLogStreams();
commonInit();
/**启动Binder线程池*/
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}
RuntimeInit.zygoteInit方法调用到了nativeZygoteInit这个native层方法,这个方法是用来启动Binder线程池的,我们接下来看代码是如何执行的。
2 NativeZygoteInit - 启动Binder线程池
nativeZygoteInit函数对用的JNI文件如下:
frameworks/base/core/jni/AndroidRuntime.cpp
/*
* JNI registration.
*/
static const JNINativeMethod gMethods[] = {android
{ "nativeFinishInit", "()V",
(void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
{ "nativeSetExitWithoutCleanup", "(Z)V",
(void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
};
通过上面JNI的gMethods数组,看出nativeZygoteInit函数对应的是JNI文件AndroidRuntime.cpp的com_android_internal_os_RuntimeInit_nativeZygoteInit函数,
static AndroidRuntime* gCurRuntime = NULL;
...
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
因为这里gCurRuntime是AndroidRuntime类型的指针,这里调用到了AppRuntime的onZygoteInit函数,代码如下所示。
frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
上面看到最终是调用了startThreadPool()方法,启动了一个Binder线程池,用来与其它进程进行通信。所以上面RuntimeInit.nativeZygoteInit
函数就是为了启动Binder线程池。接下来我们看RuntimeInit.applicationInit
函数。
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
final Arguments args;
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
接着调用到了invokeStaticMain函数:
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl;
try {
// 1
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
// 2
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
// 3
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
在注释1处通过反射生成一个class对象,这里的className是前面参数传递过来的com.android.server.SystemServer
,在注释2处通过反射找到SystemServer的main函数,注释3处直接抛出了一个MethodAndArgsCaller的异常,这个异常在哪里被处理的呢?我们回头看下ZygoteInit的main函数的最后:
public static void main(String argv[]) {
try {
...
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
从上面看到调用了caller.run(),也就是调用了MethodAndArgsCaller.run方法,源码如下
public static class MethodAndArgsCaller extends Exception
implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
看到调用的是mMethod.invoke
,即最终就调用到了SystemServer.main函数,下面我们进行分析。
3 SystemServer进程解析
frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
Looper.prepareMainLooper();
// Initialize native services.
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
/**1 创建SystemContext*/
// Initialize the system context.
createSystemContext();
// Create the system service manager.
/**2 创建SystemServiceManager*/
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
// Start services.
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();//3 启动引导服务
startCoreServices();//4 启动核心服务
startOtherServices();//5 启动其它服务
} catch (Throwable ex) {
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
run函数主要完成了以下几个工作:
- 注释1处创建createSystemContext。
- 注释2处创建SystemServiceManager,它负责启动,创建和管理系统服务。内部存储了各种启动的大约80多种服务。
- 注释3处启动了引导服务,比如ActivityManagerService、PowerManagerService、PackageManagerService。
- 注释4处启动了核心服务,如BatteryService、UsageStatsService和WebViewUpdateService。
- 注释5处则启动了CameraService、AlarmManagerService、VrManagerService等服务。
这些服务的父类基本都为SystemService, 系统将服务分为了三个类别,引导服务,核心服务和其它服务,下面通过表格列举其中一些服务:
引导服务 | 作用 |
---|---|
Installer | 系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务 |
ActivityManagerService | 负责四大组件的启动、切换、调度。 |
PowerManagerService | 计算系统中和Power相关的计算,然后决策系统应该如何反应 |
DisplayManagerService | 用来管理所有显示设备 |
UserManagerService | 多用户模式管理 |
SensorService | 为系统提供各种感应器服务 |
PackageManagerService | 用来对apk进行安装、解析、删除、卸载等等操作 |
LightsService | 管理和显示背光LED |
核心服务 | |
BatteryService | 管理电池相关的服务 |
UsageStatsService | 收集用户使用每一个APP的频率、使用时常 |
WebViewUpdateService | WebView更新服务 |
其他服务 | |
CameraService | 摄像头相关服务 |
AlarmManagerService | 全局定时器管理服务 |
InputManagerService | 管理输入事件 |
WindowManagerService | 窗口管理服务 |
VrManagerService | VR模式管理服务 |
BluetoothService | 蓝牙管理服务 |
NotificationManagerService | 通知管理服务 |
DeviceStorageMonitorService | 存储相关管理服务 |
LocationManagerService | 定位管理服务 |
AudioService | 音频相关管理服务 |
SystemServiceManager.startService
比如要启动Installer, 调用如下:
Installer installer = mSystemServiceManager.startService(Installer.class);
我们进入SystemServiceManager.startService的源码,如下:
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
// Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
// 1
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
}
...
// 2
mServices.add(service);
// 3
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + name
+ ": onStart threw an exception", ex);
}
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
在注释1处通过反射获取SystemService,这里是Installer。在注释2处将Installer添加到mServices集合中,mServices集合是用来存储SystemService集合的。注释3调用service.onStart()
启动并且返回service。
除了这种启动方式外,像PackageManagerService是通过main函数启动的,如下:
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.
/**(1)检查Package编译相关系统属性*/
PackageManagerServiceCompilerMapping.checkProperties();
/**(2)调用PackageManagerService构造方法, 同学们可以参考【PKMS构造方法】 */
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
/**(3)启用部分应用, 服务于多用户场景*/
m.enableSystemUserPackages();
/**(4)往ServiceManager中注册”package”*/
ServiceManager.addService("package", m);
return m;
}
上面注释4处的ServiceManager用来管理系统中的各种Service,用于系统C/S架构中的Binder机制通信。客户端想要使用某个服务,需要到ServiceManager中查询,然后建立通信。
SystemServer进程总结
- 启动Binder线程池建立进程间通信。
- 创建SystemServiceManager,它用于对系统服务进行创建、启动和生命周期管理。
- 启动三类大约80多种系统服务。