💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
SystemServer核心逻辑的入口是main函数,其代码如下: **SystemServer.java** ~~~ 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** ~~~ extern "C" int system_init(); static voidandroid_server_SystemServer_init1(JNIEnv* env, jobject clazz) { system_init(); //调用上面那个用extern 声明的system_init函数 } ~~~ 而system_init函数又在另外一个库libsystem_server.so中实现,代码如下: **System_init.cpp** ~~~ extern "C" status_t system_init() { LOGI("Enteredsystem_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); charpropBuf[PROPERTY_VALUE_MAX]; //判断SystemServer是否启动SurfaceFlinger服务,该值由init.rc //脚本设置,默认为零,即不启动SF服务 property_get("system_init.startsurfaceflinger",propBuf, "1"); /* 从4.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 jclassclazz = 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(); returnNO_ERROR; } ~~~ 那么,SystemServer的main函数究竟做了什么呢? 通过init1函数,辛辛苦苦从Java层穿越到Native层,做了一些初始化工作后,又通过JNI从Native层穿越到Java层去调用init2函数。 init2函数返回后,最终又回归到Native层。 是不是感觉init1和init2这两个函数的命名似曾相识,和我们初学编程时自定义的函数名非常像呢?其实代码中有一段“扭捏”的注释,解释了编写这种“初级”代码的原因。很简单,就是在对AndroidRuntime初始化前必须对一些核心服务初始化。 通过注释可看出,这段代码的作者也担心被人指责,但至少可以把函数名取得更形象一点吧?