3.2 SystemServer分析
SystemServer是由Zygote孵化而来的一个进程,通过ps命令,可知其进程名为system_server。
注意 system_server进程在DDMS中看到的进程名为system_process。
3.2.1 main函数分析
SystemServer核心逻辑的入口是main函数,其代码如下:
[—>SystemServer.java:main]
public static void main(String[]args){
if(System.currentTimeMillis()<EARLIEST_SUPPORTED_TIME){
//如果系统时钟早于1970年,则设置系统时钟从1970年开始
Slog.w(TAG,"System clock is before 1970;setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//判断性能统计功能是否开启
if(SamplingProfilerIntegration.isEnabled()){
SamplingProfilerIntegration.start();
timer=new Timer();
timer.schedule(new TimerTask(){
@Override
public void run(){
//SystemServer性能统计,每小时统计一次,统计结果输出为文件
SamplingProfilerIntegration.writeSnapshot("system_server",
null);
}//SNAPSHOT_INTERVAL定义为1小时
},SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
//和Dalvik虚拟机相关的设置,主要是内存使用方面的控制
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
//加载动态库libandroid_servers.so
System.loadLibrary("android_servers");
init1(args);//调用native的init1函数
}
main函数首先做一些初始化工作,然后加载动态库libandroid_servers.so,最后调用native的init1函数。该函数在libandroid_servers.so库中实现,其代码如下:
[—>com_android_server_SystemServer.cpp:system_init]
extern"C"int system_init();
static void android_server_SystemServer_init1(JNIEnv*env, jobject clazz)
{
system_init();//调用上面那个用extern声明的system_init函数
}
而system_init函数又在另外一个库libsystem_server.so中实现,代码如下:
[—>System_init.cpp:system_init]
extern"C"status_t system_init()
{
LOGI("Entered system_init()");
//初始化Binder系统
sp<ProcessState>proc(ProcessState:self());
//获取ServiceManager的客户端对象BpServiceManager
sp<IServiceManager>sm=defaultServiceManager();
//GrimReaper俗称死神
sp<GrimReaper>grim=new GrimReaper();
/*
下面这行代码的作用就是注册grim对象为ServiceManager死亡信息的接收者。一旦SM死亡,
Binder系统就会发送讣告信息,这样grim对象的binderDied函数就会被调用。该函数内部
将杀死(kill)自己(即SystemServer)。
笔者觉得,对于这种因挚爱离世而自杀的物体,叫死神不太合适
*/
sm->asBinder()->linkToDeath(grim, grim.get(),0);
char propBuf[PROPERTY_VALUE_MAX];
//判断SystemServer是否需要启动SurfaceFlinger服务,该值由init.rc
//脚本设置,默认为零,即不启动SF服务
property_get("system_init.startsurfaceflinger",propBuf,"1");
/*
从Android4.0开始,和显示相关的核心服务surfaceflinger可独立到另外一个进程中。
笔者认为,这可能和目前SystemServer的负担过重有关。另外,随着智能终端上HDMI的普及,
未来和显示相关的工作将会越来越繁重。将SF放在单独进程中,不仅可加强集中管理,也可充分
利用未来智能终端上多核CPU的资源
*/
if(strcmp(propBuf,"1")==0){
SurfaceFlinger:instantiate();
}
//判断SystemServer是否启动传感器服务,默认将启动传感器服务
property_get("system_init.startsensorservice",propBuf,"1");
if(strcmp(propBuf,"1")==0){
//和SF相同,传感器服务也支持在独立进程中实现
SensorService:instantiate();
}
//获得AndroidRuntime对象
AndroidRuntime*runtime=AndroidRuntime:getRuntime();
JNIEnv*env=runtime->getJNIEnv();
……//查找Java层的SystemServer类,获取init2函数的methodID
jclass clazz=env->FindClass("com/android/server/SystemServer");
……
jmethodID methodId=env->GetStaticMethodID(clazz,"init2","()V");
……//通过JNI调用Java层的init2函数
env->CallStaticVoidMethod(clazz, methodId);
//主线程加入Binder线程池
ProcessState:self()->startThreadPool();
IPCThreadState:self()->joinThreadPool();
return NO_ERROR;
}
SystemServer的main函数究通过init1函数,从Java层穿越到Native层,做了一些初始化工作后,又通过JNI从Native层穿越到Java层去调用init2函数。
init2函数返回后,最终又回归到Native层。
是不是感觉init1和init2这两个函数的命名和我们初学编程时自定义的函数名非常像呢?其实代码中有一段“扭捏”的注释,解释了编写这种“初级”代码的原因,也就是在对AndroidRuntime初始化前必须先初始化一些核心服务。