Android系统的开机画面显示过程分析(9)

简介:
    函数handle_control_message实现在system/core/init/init.c中,如下所示:
  1. void handle_control_message(const char *msg, const char *arg)  
  2. {  
  3.     if (!strcmp(msg,"start")) {  
  4.         msg_start(arg);  
  5.     } else if (!strcmp(msg,"stop")) {  
  6.         msg_stop(arg);  
  7.     } else {  
  8.         ERROR("unknown control msg '%s'\n", msg);  
  9.     }  
  10. }  
       控制类型的系统属性的名称是以"ctl."开头,并且是以“start”或者“stop”结尾的,其中,“start”表示要启动某一个服务,而“stop”表示要停止某一个服务,它们是分别通过函数msg_start和msg_stop来实现的。由于当前发生变化的系统属性是以“start”来结尾的,因此,接下来就会调用函数msg_start来启动一个名称为“bootanim”的服务。 
 
       函数msg_start实现在文件system/core/init/init.c中,如下所示:
  1. static void msg_start(const char *name)  
  2. {  
  3.     struct service *svc;  
  4.     char *tmp = NULL;  
  5.     char *args = NULL;  
  6.   
  7.     if (!strchr(name, ':'))  
  8.         svc = service_find_by_name(name);  
  9.     else {  
  10.         tmp = strdup(name);  
  11.         args = strchr(tmp, ':');  
  12.         *args = '\0';  
  13.         args++;  
  14.   
  15.         svc = service_find_by_name(tmp);  
  16.     }  
  17.   
  18.     if (svc) {  
  19.         service_start(svc, args);  
  20.     } else {  
  21.         ERROR("no such service '%s'\n", name);  
  22.     }  
  23.     if (tmp)  
  24.         free(tmp);  
  25. }  
       参数name的值等于“bootanim”,它用来描述一个服务名称。这个函数首先调用函数service_find_by_name来找到名称等于“bootanim”的服务的信息,这些信息保存在一个service结构体svc中,接着再调用另外一个函数service_start来将对应的应用程序启动起来。
 
      从前面的内容可以知道,名称等于“bootanim”的服务所对应的应用程序为/system/bin/bootanimation,这个应用程序实现在frameworks/base/cmds/bootanimation目录中,其中,应用程序入口函数main是实现在frameworks/base/cmds/bootanimation/bootanimation_main.cpp中的,如下所示:
  1. int main(int argc, char** argv)  
  2. {  
  3. #if defined(HAVE_PTHREADS)  
  4.     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);  
  5. #endif  
  6.   
  7.     char value[PROPERTY_VALUE_MAX];  
  8.     property_get("debug.sf.nobootanimation", value, "0");  
  9.     int noBootAnimation = atoi(value);  
  10.     LOGI_IF(noBootAnimation,  "boot animation disabled");  
  11.     if (!noBootAnimation) {  
  12.   
  13.         sp<ProcessState> proc(ProcessState::self());  
  14.         ProcessState::self()->startThreadPool();  
  15.   
  16.         // create the boot animation object  
  17.         sp<BootAnimation> boot = new BootAnimation();  
  18.   
  19.         IPCThreadState::self()->joinThreadPool();  
  20.   
  21.     }  
  22.     return 0;  
  23. }  

       这个函数首先检查系统属性“debug.sf.nobootnimaition”的值是否不等于0。如果不等于的话,那么接下来就会启动一个Binder线程池,并且创建一个BootAnimation对象。这个BootAnimation对象就是用来显示第三个开机画面的。由于BootAnimation对象在显示第三个开机画面的过程中,需要与SurfaceFlinger服务通信,因此,应用程序bootanimation就需要启动一个Binder线程池。
 
       BootAnimation类间接地继承了RefBase类,并且重写了RefBase类的成员函数onFirstRef,因此,当一个BootAnimation对象第一次被智能指针引用的时,这个BootAnimation对象的成员函数onFirstRef就会被调用。
       BootAnimation类的成员函数onFirstRef实现在文件frameworks/base/cmds/bootanimation/BootAnimation.cpp中,如下所示:
  1. void BootAnimation::onFirstRef() {  
  2.     status_t err = mSession->linkToComposerDeath(this);  
  3.     LOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));  
  4.     if (err == NO_ERROR) {  
  5.         run("BootAnimation", PRIORITY_DISPLAY);  
  6.     }  
  7. }  
       mSession是BootAnimation类的一个成员变量,它的类型为SurfaceComposerClient,是用来和SurfaceFlinger执行Binder进程间通信的,它是在BootAnimation类的构造函数中创建的,如下所示:
  1. BootAnimation::BootAnimation() : Thread(false)  
  2. {  
  3.     mSession = new SurfaceComposerClient();  
  4. }  
         SurfaceComposerClient类内部有一个实现了ISurfaceComposerClient接口的Binder代理对象mClient,这个Binder代理对象引用了SurfaceFlinger服务,SurfaceComposerClient类就是通过它来和SurfaceFlinger服务通信的。
         回到BootAnimation类的成员函数onFirstRef中,由于BootAnimation类引用了SurfaceFlinger服务,因此,当SurfaceFlinger服务意外死亡时,BootAnimation类就需要得到通知,这是通过调用成员变量mSession的成员函数linkToComposerDeath来注册SurfaceFlinger服务的死亡接收通知来实现的。
 
        BootAnimation类继承了Thread类,因此,当BootAnimation类的成员函数onFirstRef调用了父类Thread的成员函数run之后,系统就会创建一个线程,这个线程在第一次运行之前,会调用BootAnimation类的成员函数readyToRun来执行一些初始化工作,后面再调用BootAnimation类的成员函数htreadLoop来显示第三个开机画面。
 

 





本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967042,如需转载请自行联系原作者
目录
相关文章
|
2天前
|
Android开发
Android 如何将定制的Launcher成为系统中唯一的Launcher
Android 如何将定制的Launcher成为系统中唯一的Launcher
12 2
|
4天前
|
机器学习/深度学习 Java Shell
[RK3568][Android12.0]--- 系统自带预置第三方APK方法
[RK3568][Android12.0]--- 系统自带预置第三方APK方法
22 0
|
2天前
|
存储 Android开发
android launcher总体分析
android launcher总体分析
|
4天前
|
Java Android开发
Android OTG U盘无法显示在系统文件管理的修改
Android OTG U盘无法显示在系统文件管理的修改
6 0
|
4天前
|
安全 Android开发
修改Android系统的签名
修改Android系统的签名
15 0
|
4天前
|
安全 Android开发
Android 系统签名
Android 系统签名
14 0
|
4天前
|
Linux Android开发
Android开机不显示bootloader界面
Android开机不显示bootloader界面
8 0
Android开机不显示bootloader界面
|
4天前
|
Android开发
Android APP 隐藏系统软键盘的方法
Android APP 隐藏系统软键盘的方法
11 0
|
4天前
|
Android开发
Android修改默认system/bin/下可执行程序拥有者和权限,使用实例,只有root和系统app权限才能执行某个命令。
Android修改默认system/bin/下可执行程序拥有者和权限,使用实例,只有root和系统app权限才能执行某个命令。
12 0
|
4天前
|
JSON Android开发 数据格式
Android 打开系统文件管理器,并返回选中文件的路径
Android 打开系统文件管理器,并返回选中文件的路径
12 0