4.3.2 SystemServer的重要使命
SS诞生后,便和生父Zygote分道扬镳了,它有了自己的使命。它的使命是什么呢?代码如下所示:
pid=Zygote.forkSystemServer();
if(pid==0){//SS进程返回0,那么下面这句话就是SS的使命:
handleSystemServerProcess(parsedArgs);
}
SS调用handleSystemServerProcess来承担自己的职责。
[—>ZygoteInit.java]
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller{
//关闭从Zygote那里继承下来的Socket。
closeServerSocket();
//设置SS进程的一些参数。
setCapabilities(parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
//调用ZygoteInit函数。
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
}
现在SS走到RuntimeInit中了,它的代码在RuntimeInit.java中,如下所示:
[—>RuntimeInit.java]
public static final void zygoteInit(String[]argv)
throws ZygoteInit.MethodAndArgsCaller{
//做一些常规初始化。
commonInit();
//①native层的初始化。
zygoteInitNative();
int curArg=0;
for(/curArg/;curArg<argv.length;curArg++){
String arg=argv[curArg];
if(arg.equals("—")){
curArg++;
break;
}else if(!arg.startsWith("—")){
break;
}else if(arg.startsWith("—nice-name=")){
String niceName=arg.substring(arg.indexOf('=')+1);
//设置进程名为niceName,也就是"system_server"。
Process.setArgV0(niceName);
}
}
//startClass名为"com.android.server.SystemServer"。
String startClass=argv[curArg++];
String[]startArgs=new String[argv.length-curArg];
System.arraycopy(argv,curArg,startArgs,0,startArgs.length);
//②调用startClass,也就是com.android.server.SystemServer类的main函数。
invokeStaticMain(startClass,startArgs);
}
对于上面列举出的两个关键点(即代码中的①和②),我们一个一个地分析。
1.zygoteInitNative分析
先看zygoteInitNative,它是一个native函数,实现在AndroidRuntime.cpp中。
[—>AndroidRuntime.cpp]
static void com_android_internal_os_RuntimeInit_zygoteInit(
JNIEnv*env,jobject clazz)
{
gCurRuntime->onZygoteInit();
}
//gCurRuntime是什么?还记得我们在本章开始说的app_process的main函数吗?
int main(int argc,const char*const argv[])
{
AppRuntime runtime;//就是这个。当时我们没顾及它的构造函数,现在回过头看看。
}
//AppRuntime的定义
class AppRuntime:public AndroidRuntime
static AndroidRuntime*gCurRuntime=NULL;//gCurRuntime为全局变量。
AndroidRuntime:AndroidRuntime()
{
SkGraphics:Init();//Skia库初始化
SkImageDecoder:SetDeviceConfig(SkBitmap:kRGB_565_Config);
SkImageRef_GlobalPool:SetRAMBudget(512*1024);
gCurRuntime=this;//gCurRuntime被设置为AndroidRuntime对象自己。
}
由于SS是从zygote fork出来的,所以它也拥有zygote进程中定义的这个gCurRuntime,也就是AppRuntime对象。那么,它的onZygoteInit会干些什么呢?它的代码在App_main.cpp中,我们一起来看:
[—>App_main.cpp]
virtual void onZygoteInit()
{
//下面这些东西和Binder有关,但读者可以先不管它。
sp<ProcessState>proc=ProcessState:self();
if(proc->supportsProcesses()){
proc->startThreadPool();//启动一个线程,用于Binder通信。
}
}
一言以蔽之,SS调用zygoteInitNative后,将与Binder通信系统建立联系,这样SS就能够使用Binder了。关于Binder的知识,将在第6章中详细介绍,大家现在不必关注。
2.invokeStaticMain分析
再来看第二个关键点invokeStaticMain。代码如下所示:
[—>RuntimeInit.java]
private static void invokeStaticMain(String className,String[]argv)
throws ZygoteInit.MethodAndArgsCaller{
……//注意我们的参数,className为"com.android.server.SystemServer"。
Class<?>cl;
try{
cl=Class.forName(className);
}catch(ClassNotFoundException ex){
throw new RuntimeException(
"Missing class when invoking static main"+className,
ex);
}
Method m;
try{
//找到com.android.server.SystemServer类的main函数,肯定有地方要调用它。
m=cl.getMethod("main",new Class[]{String[].class});
}catch(NoSuchMethodException ex){
……
}catch(SecurityException ex){
……
}
int modifiers=m.getModifiers();
if(!(Modifier.isStatic(modifiers)&&Modifier.isPublic(modifiers))){
……
}
//抛出一个异常,为什么不在这里直接调用上面的main函数呢?
throw new ZygoteInit.MethodAndArgsCaller(m,argv);
}
invokeStaticMain竟然抛出了一个异常,它是在哪里被截获的呢?原来是在ZygoteInit的main函数中。请看这段代码:
注意 我们所在的进程是system_server。
[—>ZygoteInit.java]
……
if(argv[1].equals(“true”)){
//在SS进程中,抛出一个异常MethodAndArgsCaller。
startSystemServer();
……
catch(MethodAndArgsCaller caller){
//被截获,调用caller的run函数。
caller.run();
}
再来看看MethodAndArgsCaller的run函数。
public void run(){
try{
//这个mMethod为com.android.server.SystemServer的main函数。
mMethod.invoke(null,new Object[]{mArgs});
}catch(IllegalAccessException ex){
……
}
}
抛出的这个异常最后会导致com.android.server.SystemServer类的main函数被调用。不过这里有一个疑问,为什么不在invokeStaticMain那里直接调用,而是采用这种抛异常的方式呢?我对这个问题的看法是:
这个调用是在ZygoteInit.main中,相当于Native的main函数,即入口函数,位于堆栈的顶层。如果不采用抛异常的方式,而是在invokeStaticMain那里调用,则会浪费之前函数调用所占用的一些调用堆栈。
注意 关于这个问题的深层思考,读者可以利用fork和exec的知识。个人认为这种抛异常的方式是对exec的一种近似模拟,因为后续的工作将交给com.android.server.SystemServer类来处理。
3.SystemServer的真面目
ZygoteInit分裂产生的SS,其实就是为了调用com.android.server.SystemServer的main函数,这简直就是改头换面!下面就来看看这个真实的main函数,代码如下所示:
[—>SystemServer.java]
public static void main(String[]args){
……
//加载libandroid_servers.so。
System.loadLibrary("android_servers");
//调用native的init1函数。
init1(args);
}
其中main函数将加载libandroid_server.so库,这个库所包含的源码文件在文件夹framework/base/services/jni下。
(1)init1分析
init1是native函数,在com_android_server_SystemServer.cpp中实现。来看看它,代码如下所示:
[—>com_android_server_SystemServer.cpp]
extern“C”int system_init();
static void android_server_SystemServer_init1(JNIEnv*env,jobject clazz)
{
system_init();//调用另外一个函数。
}
system_init的实现在system_init.cpp中,它的代码如下所示:
[—>system_init.cpp]
extern“C”status_t system_init()
{
//下面这些调用和Binder有关,我们会在第6章中讲述,这里先不必管它。
sp<ProcessState>proc(ProcessState:self());
sp<IServiceManager>sm=defaultServiceManager();
sp<GrimReaper>grim=new GrimReaper();
sm->asBinder()->linkToDeath(grim,grim.get(),0);
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger",propBuf,"1");
if(strcmp(propBuf,"1")==0){
//SurfaceFlinger服务在system_server进程中创建。
SurfaceFlinger:instantiate();
}
……
//调用com.android.server.SystemServer类的init2函数。
AndroidRuntime*runtime=AndroidRuntime:getRuntime();
runtime->callStatic("com/android/server/SystemServer","init2");
//下面这几个函数的调用和Binder通信有关,具体内容在第6章中介绍。
if(proc->supportsProcesses()){
ProcessState:self()->startThreadPool();
//调用joinThreadPool后,当前线程也加入到Binder通信的大潮中。
IPCThreadState:self()->joinThreadPool();
}
return NO_ERROR;
}
init1函数创建了一些系统服务,然后把调用线程加入到Binder通信中了。不过其间还通过JNI调用了com.android.server.SystemServer类的init2函数,下面就来看看这个init2函数。
(2)init2分析
init2在Java层,代码在SystemServer.java中,如下所示:
[—>SystemServer.java]
public static final void init2(){
Thread thr=new ServerThread();
thr.setName(“android.server.ServerThread”);
thr.start();//启动一个ServerThread。
}
启动了一个ServerThread线程。请直接看它的run函数。这个函数比较长,大概看看它干了什么即可。
[—>SystemServer.java:ServerThread的run函数]
public void run(){
……
//启动Entropy Service。
ServiceManager.addService("entropy",new EntropyService());
//启动电源管理服务。
power=new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE,power);
//启动电池管理服务。
battery=new BatteryService(context);
ServiceManager.addService("battery",battery);
//初始化看门狗,在本章的拓展内容中将介绍关于看门狗的知识。
Watchdog.getInstance().init(context,battery,power,alarm,
ActivityManagerService.self());
//启动WindowManager服务。
wm=WindowManagerService.main(context,power,
factoryTest!=SystemServer.FACTORY_TEST_LOW_LEVEL);
ServiceManager.addService(Context.WINDOW_SERVICE,wm);
//启动ActivityManager服务。
(ActivityManagerService)ServiceManager.getService("activity"))
.setWindowManager(wm);
……//总之,系统各项重要的服务都在这里启动。
Looper.loop();//进行消息循环,然后处理消息。关于这部分内容参见第5章。
}
init2函数比较简单,就是单独创建一个线程,用以启动系统的各项服务,至此,读者或许能理解SS的重要性了吧?
Java世界的核心Service都在这里启动,所以它非常重要。
说明 本书不对这些Service做进一步的分析,今后有机会再专门介绍。