Android启动过程详解(4)——SystemServer
上一篇博客介绍了ZygoteService的启动过程,在Zygote的启动后首先就会启动SystemServer,所以SystemServer可以看做是Zygote嫡长子。能够成为嫡长子的必然有着非常重要的作用,的确是这样,Android应用框架中的各种Service,例如ActivityManagerService,PacakgeManagerService,WindowManagerService等等重要的系统服务都是在SystemServer中启动的。这篇博客我们就来看看SystemServer的启动过程。
1.SystemServer启动
SystemServer是通过Zygote.startSystemServer来启动的,所以首先来看看对应的代码,其对应的实现在dalvik_system_Zygote.c中,这是一个native函数:
[-->dalvik_system_Zygote.c]static voidDalvik_dalvik_system_Zygote_forkSystemServer( const u4* args, JValue* pResult){ pid_tpid; //根据参数,fork一个子进程 pid =forkAndSpecializeCommon(args); if (pid > 0) { int status; gDvm.systemServerPid = pid;//保存system_server的进程id //函数退出前须先检查刚创建的子进程是否退出了。 if(waitpid(pid, &status, WNOHANG) == pid) { //如果system_server退出了,Zygote直接干掉了自己 //看来Zygote和SS的关系异常紧密,简直是生死与共! kill(getpid(), SIGKILL); } } RETURN_INT(pid);}
通过上面的代码可以看出,Zygote会fork出一个进程作为SystemServer的宿主,具体的操作是在forkAndSpecializeCommon
中完成。在完成创建SystemServer的进程之后,Zygote会检查其对应的进程是否退出,如果退出了,Zygote也会杀死自己。
下面,再看看forkAndSpecializeCommon,代码如下所示:
[-->dalvik_system_Zygote.c]static pid_t forkAndSpecializeCommon(const u4*args){ pid_tpid; uid_tuid = (uid_t) args[0]; gid_tgid = (gid_t) args[1]; ArrayObject* gids = (ArrayObject *)args[2]; u4debugFlags = args[3]; ArrayObject *rlimits = (ArrayObject *)args[4]; //设置信号处理,待会儿要看看这个函数。 setSignalHandler(); pid =fork(); //fork子进程 if (pid== 0) { //对子进程要根据传入的参数做一些处理,例如设置进程名,设置各种id(用户id,组id等) }......}
最后看看setSignalHandler函数,它由Zygote在fork子进程前调用,代码如下所示:
[-->dalvik_system_Zygote.c]static void setSignalHandler(){ interr; structsigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigchldHandler; err =sigaction (SIGCHLD, &sa, NULL);//设置信号处理函数,该信号是子进程死亡的信号}
直接看这个信号处理函数sigchldHandler
static void sigchldHandler(int s){ pid_tpid; intstatus; while((pid = waitpid(-1, &status, WNOHANG)) > 0) { } else if (WIFSIGNALED(status)) { } } //如果死去的子进程是SS,则Zygote把自己也干掉了,这样就做到了生死与共! if(pid == gDvm.systemServerPid) { kill(getpid(), SIGKILL); } }
2.SystemServer的作用
接下来看看SystemServer在启动的过程中具体做了些什么。
pid =Zygote.forkSystemServer(); if(pid == 0) { //子进程处理逻辑: handleSystemServerProcess(parsedArgs); }
从代码中可以看到,当SystemServer被fork出来之后,会调用handleSystemServerProcess来处理自身的启动逻辑。
[-->ZygoteInit.java]private static void handleSystemServerProcess( ZygoteConnection.ArgumentsparsedArgs) 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(); intcurArg = 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);}
上面的代码有两个地方比较重要:
- zygoteInitNative,执行native层的初始化
- invokeStaticMain(startClass, startArgs):执行SystemServer的main函数。
接下来分别讲一下以上两点:
2.1 zygoteInitNative
该函数最终会调用AppMain的onZygoteInit函数:
[-->App_main.cpp] virtual void onZygoteInit() { //下面这些东西和Binder有关系 sp proc = ProcessState::self(); if(proc->supportsProcesses()) { proc->startThreadPool();//启动一个线程,用于Binder通信。 } }
2.2 invokeStaticMain
[-->RuntimeInit.java]private static void invokeStaticMain(StringclassName, 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 wheninvoking 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))) { ...... } //抛出一个异常 throw new ZygoteInit.MethodAndArgsCaller(m, argv); }
这个函数比较奇怪的一点是,在加载到com.android.server.SystemServer
类以及找到其对应的main函数之后,并没有直接启动该函数,而是抛出了一个异常,这个异常会在ZygoteInit的main函数中catch,然后才启动对应的面函数。这样做的原因是为了清空堆栈,让用户看到堆栈的栈顶是ZygoteInit.main。
接下来再来看看Zygote在启动后都干了些什么,首先来看看main函数:
[-->SystemServer.java]public static void main(String[] args) { ...... //加载libandroid_servers.so System.loadLibrary("android_servers"); //调用native的init1函数。 init1(args);}
所以启动过程转移到了init1函数中:
init1是native函数,在com_android_server_SystemServer.cpp中实现:
[-->com_android_server_SystemServer.cpp]extern "C" int system_init();static voidandroid_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 proc(ProcessState::self()); sp sm = defaultServiceManager(); spgrim = new GrimReaper(); sm->asBinder()->linkToDeath(grim, grim.get(), 0); charpropBuf[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通信有关。 if (proc->supportsProcesses()) { ProcessState::self()->startThreadPool(); //调用joinThreadPool后,当前线程也加入到Binder通信的大潮中 IPCThreadState::self()->joinThreadPool(); } returnNO_ERROR;}
init1函数创建了一些系统服务,然后把调用线程加入Binder通信中。不过其间还通过JNI调用了com.android.server.SystemServer类的init2函数,下面就来看看这个init2函数。init2在Java层,代码在SystemServer.java中:
[-->SystemServer.java]public static final void init2() { Threadthr = 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函数比较简单,就是单独创建一个线程,用以启动系统各项服务。至此,SystemServer启动完毕。
更多相关文章
- Android之浅谈activity生命周期
- Android(安卓)Service两种启动启动方式
- Android开发中遇到的bug(2)
- Android(安卓)Binder Mechanism (3) -- 如何向系统注册Service
- 使用BroadcastReceiver实现开机启动Service或Activity(以便收藏)
- android service 学习(上) 音乐播放
- android studio使用jni调用opencv库实现图片转换【详细实例】(二)
- Android(安卓)MediaRecorder录制视频提示start failed的解决办法
- 设备驱动-----Android关机流程总结