【android】【Bootanimation】Bootanimation---启动和退出
16lz
2021-01-22
- 题序
- Bootanimation的启动
其中: class <name> # 设置名称为name的类别,感觉有点像开机启动service的优先级,默认的class名称为default user <effectuserid> # 设置服务进程的effective user ID group <groupname> [ <groupname> ]* # 设置服务进程的effective group ID(第一个参数)和supplementary group IDs(第二个到最后) disabled # 设置后,不能自动地通过class名称启动,必须显式地通过service名称启动,或是表示init进程创建只是创建它,但不立刻执行。 oneshot# 选项表示该服务只启动一次,而如果没有oneshot选项,这个可执行程序会一直存在---如果可执行程序被杀死,则会重新启动。 其实在这个时候,因为设置了bootanim的属性为disabled的,这就意味着在init.c中,只是创建了bootanim这个service,但是其实并没有去启动他。那么bootanim到底在什么时候启动呢。 还是要回到init的概念中,Android系统在init.rc中定义了很多Service,具体定义格式可以参考《Android Platform Developer’s Guide》中的“Android Init Language”。Init.rc中定义的Service将会被Init进程创建,其中已经定义的服务就包含bootanimation。每一项服务必须在/init.rc中定义.Android系统启动时,init守护进程将解析init.rc和启动属性服务,属性“ ctl.start ”和“ctl.stop ”是用来启动和停止服务的。一旦收到设置“ ctrl.start ”属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入“ init.svc.<服务名>“属性中 。 也就是说启动bootanim必须显式调用ctrl.start,bootanim才能够开始启动,这就是disabled这个属性的神奇之所在。 在surfaceFlinger.cpp中,surfaceFlinger init()的时候,会通过调用startBootAnim()来启动bootanima service。 #startBootAnim() @ surfaceFlinger.cpp void SurfaceFlinger::startBootAnim(){ property_set("service.bootanim.exit","0"); property_set("ctl.start","bootanim"); } 还记不记得在init.c的main()函数中,在完全所有的初始化,如创建文件系统,解析init.rc,初始化property workspace等之后,进入了一个死循环。这个循环其实是在等待事件,如property setting,signal 及keychord等。 #main() @ init.c void main() { ..... for(;;){ ..... for(i = 0; i < fd_count; i++) { if(ufds[i].revents == POLLIN) { if(ufds[i].fd == get_property_set_fd()) handle_property_set_fd(); else if(ufds[i].fd == get_keychord_fd()) handle_keychord(); else if(ufds[i].fd == get_signal_fd()) handle_signale(); } } } return 0; } ok,到这儿之后,咱们再回到bootanim来。其实对于bootanim的最先入口,就是bootanimation_main().cpp中的main()函数。 #main() @ bootanimation_main.cpp
- intmain(intargc,char**argv)
- {
- #ifdefined(HAVE_PTHREADS)
- setpriority(PRIO_PROCESS,0,ANDROID_PRIORITY_DISPLAY);
- #endif
- charvalue[PROPERTY_VALUE_MAX];
- property_get("debug.sf.nobootanimation",value,"0");
- intnoBootAnimation=atoi(value);
- LOGI_IF(noBootAnimation,"bootanimationdisabled");
- if(!noBootAnimation){
- sp<ProcessState>proc(ProcessState::self());
- ProcessState::self()->startThreadPool();
- sp<BootAnimation>boot=newBootAnimation();
- IPCThreadState::self()->joinThreadPool();
- }
- return0;
- }
- Bootanimtion的退出
property_get(EXIT_PROP_NAME, value, "0");//EXIT_PROP_NAME为字符串service.bootanim.exit
int exitnow = atoi(value);
if (exitnow) {
requestExit();
}} 在android的thread类提供的方法中,有一个曰为requestexit()的api接口,其介绍如下: virtual void requestExit();//ask this object's thread to exit,asynchronous,this function can be called in other thread 从上面CheckExit的实现中,可以看到,要能够执行RequestExit(),需要"service.bootanim.exit"的属性设置成1。 那么这个属性在启动的过程中,已经把这个属性设置成0咯,那么又是在哪个地方将其设置成1呢。 这个其实也是surfaceFlinger干的事情。 # bootFinished() @ surfaceFlinger.cpp void SurfaceFlinger::bootFinished() { ..... property_set("service.bootanim.exit","1"); } android的thread还提供了一个额外的api函数exitPending,用来查看是否执行退出正常。 bool exitPending() const;//returns true if requestExit() has been called 也就是说如果requestExit()成功,则退出,否则再做一次循环。 当然,bootanimation也存在异常退出的情况,就是binder died。 # binderDied() @ BootAnimation.cpp void BootAnimation::binderDied(const wp<IBinder>& who) { kill(getpid(),SIGKILL); requesetExit(); } 参考文献: 【1】http://blog.csdn.net/ceko_wu/article/details/8286182 【2】http://www.tuicool.com/articles/raIFvq更多相关文章
- java漏洞成黑客目标微软呼吁用户更新软件
- Java记录 -88- 利用反射机制调用对象的私有方法和属性
- 包含带标记的值的XML属性文件
- JAVA中的反射只获取属性的get方法
- 如何在Spring中读取具有相同键的多个属性?
- 为泛型类的泛型方法的属性赋值 - Java
- 如何在Spring Data(JPA)派生查询中按多个属性排序?