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

简介:
   WindowManagerService类的成员函数performEnableScreen的实现如下所示:
 
 
  1. public class WindowManagerService extends IWindowManager.Stub   
  2.         implements Watchdog.Monitor {   
  3.     ......   
  4.    
  5.     public void performEnableScreen() {   
  6.         synchronized(mWindowMap) {   
  7.             if (mDisplayEnabled) {   
  8.                 return;   
  9.             }   
  10.             if (!mSystemBooted) {   
  11.                 return;   
  12.             }   
  13.    
  14.             ......   
  15.    
  16.             mDisplayEnabled = true;   
  17.             ......   
  18.    
  19.             try {   
  20.                 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");   
  21.                 if (surfaceFlinger != null) {   
  22.                     //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");   
  23.                     Parcel data = Parcel.obtain();   
  24.                     data.writeInterfaceToken("android.ui.ISurfaceComposer");   
  25.                     surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,   
  26.                                             data, null0);   
  27.                     data.recycle();   
  28.                 }   
  29.             } catch (RemoteException ex) {   
  30.                 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");   
  31.             }   
  32.         }   
  33.    
  34.         ......   
  35.     }   
  36.    
  37.     ......   
  38. }   

        WindowManagerService类的另外一个成员变量mDisplayEnabled用来描述WindowManagerService是否已经初始化过系统的屏幕了,只有当它的值等于false,并且系统已经完成启动,即WindowManagerService类的成员变量mSystemBooted等于true的情况下,WindowManagerService类的成员函数performEnableScreen才通知SurfaceFlinger服务停止显示开机动画。
 
        注意,WindowManagerService类的成员函数performEnableScreen是通过一个类型为IBinder.FIRST_CALL_TRANSACTION的进程间通信请求来通知SurfaceFlinger服务停止显示开机动画的。
        在SurfaceFlinger服务,类型为IBinder.FIRST_CALL_TRANSACTION的进程间通信请求被定义为停止显示开机动画的请求,如下所示:
  1. class BnSurfaceComposer : public BnInterface<ISurfaceComposer>  
  2. {  
  3. public:  
  4.     enum {  
  5.         // Note: BOOT_FINISHED must remain this value, it is called from  
  6.         // Java by ActivityManagerService.  
  7.         BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,  
  8.         ......  
  9.     };  
  10.   
  11.     virtual status_t    onTransact( uint32_t code,  
  12.                                     const Parcel& data,  
  13.                                     Parcel* reply,  
  14.                                     uint32_t flags = 0);  
  15. };  
        BnSurfaceComposer类定义在文件frameworks/base/include/surfaceflinger/ISurfaceComposer.h中,它是SurfaceFlinger服务所要继承的Binder本地对象类,其中。当SurfaceFlinger服务接收到类型为IBinder::FIRST_CALL_TRANSACTION,即类型为BOOT_FINISHED的进程间通信请求时,它就会将该请求交给它的成员函数bootFinished来处理。
 
        SurfaceFlinger服务的成员函数bootFinished实现在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中,如下所示:
  1. void SurfaceFlinger::bootFinished()  
  2. {  
  3.     const nsecs_t now = systemTime();  
  4.     const nsecs_t duration = now - mBootTime;  
  5.     LOGI("Boot is finished (%ld ms)"long(ns2ms(duration)) );  
  6.     mBootFinished = true;  
  7.     property_set("ctl.stop""bootanim");  
  8. }  
       这个函数主要就是将系统属性“ctl.stop”的值设置为“bootanim”。前面提到,每当有一个系统属性发生变化时,init进程就会被唤醒,并且调用运行在它里面的函数handle_property_set_fd来处理这个系统属性变化事件。在我们这个场景中,由于被改变的系统属性的名称是以"ctl."开头的,即被改变的系统属性是一个控制类型的属性,因此,接下来函数handle_property_set_fd又会调用另外一个函数handle_control_message来处理该系统属性变化事件。
 
       函数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. }  
       从前面的调用过程可以知道,参数msg和arg的值分别等于"stop"和“bootanim”,这表示要停止执行名称为“bootanim”的服务,这是通过调用函数msg_stop来实现的。   
 
       函数msg_stop也是实现在文件system/core/init/init.c中,如下所示:
  1. static void msg_stop(const char *name)  
  2. {  
  3.     struct service *svc = service_find_by_name(name);  
  4.   
  5.     if (svc) {  
  6.         service_stop(svc);  
  7.     } else {  
  8.         ERROR("no such service '%s'\n", name);  
  9.     }  
  10. }  
       这个函数首先调用函数service_find_by_name来找到名称等于name,即“bootanim”的服务,然后再调用函数service_stop来停止这个服务。
 
       前面提到,名称为“bootanim”的服务对应的应用程序即为/system/bin/bootanimation。因此,停止名称为“bootanim”的服务即为停止执行应用程序/system/bin/bootanimation,而当应用程序/system/bin/bootanimation停止执行的时候,开机动画就会停止显示了。
       至此,Android系统的三个开机画面的显示过程就分析完成了。通过这个三个开机画面的显示过程分析,我们学习到:
       1. 在内核层,系统屏幕是使用一个称为帧缓冲区的硬件设备来描述的,而用户空间的应用程序可以通过设备文件/dev/fb0或者/dev/graphics/fb0来操作这个硬件设备。实际上,帧缓冲区本身并不是一个真正的硬件,它只不过是对显卡的一个抽象表示,不过,我们通过访帧缓冲区就可以间接地操作显卡内存以及显卡中的其它寄存器。
       2. OpenGL是通过EGL接口来渲染屏幕,而EGL接口是通过ANativeWindow类来间接地渲染屏幕的。我们可以将ANativeWindow类理解成一个Android系统的本地窗口类,即相当于是Windows系统中的窗口句柄概念,它最终是通过文件/dev/fb0或者/dev/graphics/fb0来渲染屏幕的。
       3. init进程在启动的过程中,会将另外一个ueventd进程也启动起来。ueventd进程对应的可执行文件与init进程对应的可执行文件均为/init,不过ueventd进程主要负责处理内核发出的uevent事件,即负责管理系统中的设备文件。
       4. 每当我们设置一个系统属性的时候,init进程都会接收到一个系统属性变化事件。当发生变化的系统属性的名称等于“ctl.start”或者“ctl.stop”,那么实际上是向init进程发出一个启动或者停止服务的命令。
       前面第1点和第2点的知识是与Android系统的UI实现相关的,而后面第3点和第4点是两个额外获得的知识点。
       本文的目的并不是单纯为了介绍Android系统的开机画面,而是希望能够以Android系统的开机画面来作为切入点来分析Android系统的UI实现。在后面的文章中,我们就会根据本文所涉及到的知识点,来展开分析Android系统的UI实现,敬请关注。




本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967049,如需转载请自行联系原作者
目录
相关文章
|
2月前
|
存储 Shell Android开发
基于Android P,自定义Android开机动画的方法
本文详细介绍了基于Android P系统自定义开机动画的步骤,包括动画文件结构、脚本编写、ZIP打包方法以及如何将自定义动画集成到AOSP源码中。
53 2
基于Android P,自定义Android开机动画的方法
|
1月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比分析
在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统无疑是主角。它们各自拥有独特的特点和优势,为开发者提供了不同的开发环境和工具。本文将深入浅出地探讨安卓和iOS开发环境的主要差异,包括开发工具、编程语言、用户界面设计、性能优化以及市场覆盖等方面,旨在帮助初学者更好地理解两大平台的开发特点,并为他们选择合适的开发路径提供参考。通过比较分析,我们将揭示不同环境下的开发实践,以及如何根据项目需求和目标受众来选择最合适的开发平台。
37 2
|
2月前
|
Android开发
基于android-11.0.0_r39,系统应用的手动签名方法和过程
本文介绍了基于Android 11.0.0_r39版本进行系统应用手动签名的方法和解决签名过程中遇到的错误,包括处理`no conscrypt_openjdk_jni-linux-x86_64`和`RegisterNatives failed`的问题。
112 2
|
2月前
|
JavaScript 前端开发 Java
[Android][Framework]系统jar包,sdk的制作及引用
[Android][Framework]系统jar包,sdk的制作及引用
47 0
|
4天前
|
IDE Android开发 iOS开发
探索安卓与iOS系统的技术差异:开发者的视角
本文深入分析了安卓(Android)与苹果iOS两大移动操作系统在技术架构、开发环境、用户体验和市场策略方面的主要差异。通过对比这两种系统的不同特点,旨在为移动应用开发者提供有价值的见解,帮助他们在不同平台上做出更明智的开发决策。
|
4天前
|
Ubuntu Shell API
Ubuntu 64系统编译android arm64-v8a 的openssl静态库libssl.a和libcrypto.a
Ubuntu 64系统编译android arm64-v8a 的openssl静态库libssl.a和libcrypto.a
|
19天前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
|
22天前
|
监控 Android开发 iOS开发
深入探索安卓与iOS的系统架构差异:理解两大移动平台的技术根基在移动技术日新月异的今天,安卓和iOS作为市场上最为流行的两个操作系统,各自拥有独特的技术特性和庞大的用户基础。本文将深入探讨这两个平台的系统架构差异,揭示它们如何支撑起各自的生态系统,并影响着全球数亿用户的使用体验。
本文通过对比分析安卓和iOS的系统架构,揭示了这两个平台在设计理念、安全性、用户体验和技术生态上的根本区别。不同于常规的技术综述,本文以深入浅出的方式,带领读者理解这些差异是如何影响应用开发、用户选择和市场趋势的。通过梳理历史脉络和未来展望,本文旨在为开发者、用户以及行业分析师提供有价值的见解,帮助大家更好地把握移动技术发展的脉络。
|
18天前
|
Dart 开发工具 Android开发
在 Android 系统上搭建 Flutter 环境的具体步骤是什么?
在 Android 系统上搭建 Flutter 环境的具体步骤是什么?
|
26天前
|
安全 Linux Android开发
探索安卓与iOS的安全性差异:技术深度分析
本文深入探讨了安卓(Android)和iOS两个主流操作系统平台在安全性方面的不同之处。通过比较它们在架构设计、系统更新机制、应用程序生态和隐私保护策略等方面的差异,揭示了每个平台独特的安全优势及潜在风险。此外,文章还讨论了用户在使用这些设备时可以采取的一些最佳实践,以增强个人数据的安全。