Android应用程序与Su易做图ceFlinger服务的连接过程分析
前文在描述Android应用程序和Su易做图ceFlinger服务的关系时提到,每一个有UI的Android应用程序都需要与Su易做图ceFlinger服务建立一个连接,以便可以通过这个连接来请求Su易做图ceFlinger服务为它创建和渲染Su易做图ce。在本文中,我们将以Android系统的开机动画应用程序为例,详细描述Android应用程序是如何与Su易做图ceFlinger服务建立连接的。
Android系统的开机动画是由应用程序bootanimation来实现的,它位于/system/bin目录下,它的具体实现可以参考Android系统的开机画面显示过程分析一文。为什么要选择Android系统的开机动画来分析Android应用程序与Su易做图ceFlinger服务的连接过程呢?首先,负责实现开机动画的应用程序bootanimation也是一个Android应用程序,只不过它是使用C++语言来开发的;其次,应用程序bootanimation是与UI相关的,即它与使用Java语言来开发的标准Android应用程序一样,都需要使用Su易做图ceFlinger服务来创建和渲染自己的Su易做图ce,即开机动画;第三,由于应用程序bootanimation不涉及用户输入,即不需要与用户进行交互(触摸屏、键盘等),因此它能够以最简洁的方式来体现Android应用程序与Su易做图ceFlinger服务的关系。
从前面Android系统的开机画面显示过程分析一文可以知道,Android系统的开机动画是主要一个BootAnimation对象来实现,这个BootAnimation对象在构造的时候,会在内部创建一个Su易做图ceComposerClient对象来负责创建一个到Su易做图ceFlinger服务的连接。
BootAnimation类的构造函数实现在文件frameworks/base/cmds/bootanimation/BootAnimation.cpp中,如下所示:
[cpp]
BootAnimation::BootAnimation() : Thread(false)
{
mSession = new Su易做图ceComposerClient();
}
mSession是BootAnimation类的成员变量,它是一个类型为Su易做图ceComposerClient的强指针,即sp<Su易做图ceComposerClient>。Android系统的智能指针的相关知识,可以参考Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析一文。
在Su易做图ceComposerClient类内部,有一个类型为sp<ISu易做图ceComposerClient>的成员变量mClient,如图1所示:
图1 Su易做图ceComposerClient的结构示意图
Su易做图ceComposerClient类的成员变量mClient指向的实际上是一个类型为BpSu易做图ceComposerClient的Binder代理对象,而这个类型为BpSu易做图ceComposerClient的Binder代理对象引用的是一个类型为Client的Binder本地对象。在前面Android应用程序与Su易做图ceFlinger服务的关系概述和学习计划一文中提到,类型为Client的Binder本地对象是由Su易做图ceFlinger服务来负责创建的,并且运行在Su易做图ceFlinger服务中,用来代表使用Su易做图ceFlinger服务的一个客户端,即一个与UI相关的Android应用程序。
由于Client类和BpSu易做图ceComposerClient类分别是一个Binder本地对象类和一个Binder代理对象类,它们都是根据Android系统在应用程序框架层提供的Binder进程间通信库来实现的,它们的实现结构图分别如图2和图3所示:
图2 Client类的实现结构图
图3 BpSu易做图ceComposerClient类的实现结构图
在图2和图3中,涉及到了比较多的Binder进程间通信库的类,需要读者对Android系统的Binder进程间通信机制有一定的理解和认识。在前面的Android进程间通信(IPC)机制Binder简要介绍和学习计划一系列文章,我们已经学习过Android系统的Binder进程间通信机制了,这里不再详述。
图2和图3给我们最重要的信息是Client类和BpSu易做图ceComposerClient类均实现了类型为ISu易做图ceComposerClient的Binder接口。ISu易做图ceComposerClient接口有两个重要的成员函数getControlBlock和createSu易做图ce,它们定义在文件frameworks/base/include/su易做图ceflinger/ISu易做图ceComposerClient.h中,如下所示:
[cpp]
class ISu易做图ceComposerClient : public IInte易做图ce
{
public:
......
virtual sp<IMemoryHeap> getControlBlock() const = 0;
......
/*
* Requires ACCESS_SURFACE_FLINGER permission
*/
virtual sp<ISu易做图ce> createSu易做图ce( su易做图ce_data_t* data,
int pid,
const String8& name,
DisplayID display,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags) = 0;
......
};
其中,成员函数getControlBlock用来获得由Su易做图ceFlinger服务创建的一块用来传递UI元数据的匿名共享内存,而成员函数createSu易做图ce用来请求Su易做图ceFlinger服务创建一个Su易做图ce。从前面Android应用程序与Su易做图ceFlinger服务的关系概述和学习计划一文可以知道,用来传递UI元数据的匿名共享内存最终会被结构化为一个SharedClient对象,这个SharedClient对象在每个应用程序进程中至多存在一个。在接下来的两篇文章中,我们再详细分析ISu易做图ceComposerClient接口的成员函数getControlBlock和createSu易做图ce的实现。
理解了Su易做图ceComposerClient、Client以及BpSu易做图ceComposerClient这三个类的关系之后,接下来我们就可以分析Android系统的开机动画应用程序bootanimation是如何与Su易做图ceFlinger服务建立连接的。
从图1可以知道,Su易做图ceComposerClient类继承了RefBase类,因此,当BootAnimation类在构造函数创建了一个Su易做图ceComposerClient对象,并且将这个对象赋值给类型为sp<Su易做图ceComposerClient>的智能指针mSession时,就会导致Su易做图ceComposerClient类的成员函数onFirstRef被调用,而Su易做图ceComposerClient类的成员函数onFirstRef在调用的过程中,就会在应用程序bootanimation与Su易做图ceFlinger服务建立一个连接,这个过程如图4所示:
图4 Android应用程序与Su易做图ceFlinger服务的连接过程
接下来,我们就详细分析每一个步骤。
Step 1. Su易做图ceComposerClient::onFirstRef
[cpp]
void Su易做图ceComposerClient::onFirstRef()
{
sp<ISu易做图ceComposer> sm(getComposerService());
if (sm != 0) {
&nb
补充:移动开发 , Android ,