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做进一步的分析,今后有机会再专门介绍。