Android - Binder应用分析

1.1.1           机制

1.1.1.1          摘录

1.1.1.1.1      Android-Binder框架在Framework层的C++中的使用

简单来说,Binder就是规定了客户端和服务端通信的一堆API,这些API被定义在一个接口当中。假设名字为IMyName,注意,一定是I+名字的结构。这个接口一定要继承IInterface。现在,这个IMyName就是Binder的client端与server端通信的协议了。

然后,我们通过IMyName扩展出分别用于client端和server端的接口,BpInterface和 BnInterface。通过这两个接口,client端和server端分别实现了两个类BpMyName和 BnMyName。

最后,BpMyName和BnMyName中都对每个IMyName中的接口做了实现。

BpMyName中实现每个接口时,都是调用IBinder.transact()并传入相应方法的ID来做到。

而BnMyName就要复杂一些。首先,定义一个类SomeClass来继承并实现BnMyName,这个类在命名上没有要求。在 SomeClass中对IMyName中每个接口都做了实现。在BnMyName中有一个onTransact方法,它与BpMyName中调用 IBinder.transact方法是对应的。这样,在BnMyName的onTransact方法中,根据不同的code调用不同的IMyName中的方法,而这些方法都是在SomeClass中实现的。

下面的图示意一下,可能更清楚:

IInterface

|

IMyName

| |

BpInterface BnInterface

| |

BpMyName BnMyName

|

SomeClass

当某个类使用到了IMyName中的API时,你会发现IMyName仅是个接口,里面的API全是抽象的。要找到这个API的实现,就需要根据上面示意的层次找到这个SomeClass类,这个类在命名上没有什么特征,只有一点儿,它继承了BnMyName。

1.1.2           服务

声明一个服务时,一般该服务都要继承BinderService<xxx>和Bnxxx。

1.1.2.1          BinderService

它是Binder服务模块要继承的基类,主要用于将该Binder服务注册到ServiceManager中。如CameraService。

当然也不是服务模块必须继承BinderService,如MediaPlayerService。

要成为一个服务端,最重要的是往ServiceManager注册。

1.1.2.2          Bnxxx

Bnxxx是Service要继承的基类,它负责和客户端通信。所有的Bnxxx都只有一个函数onTransact,它是根据收到的消息码调用相应的Service函数进行处理。

Bnxxx继承Ixxx和BBinder,Ixxx定义的服务端和客户端之间的通信接口;BBinder定义了onTransact。

1.1.3           客户端

1.1.3.2          Bpxxx

是service在客户端的代理(镜像),客户端要和service通信,就要通过Bpxxx句柄和Bnxxx通信,然后Bnxxx再调用service相关方法处理。
Bpxxx在客户端的进程,Bnxxx在service的进程,两个之间的接口就是Ixxx定义的接口,每个Ixxx声明中,都会有一个定义了很多功能代号的enum,Bp就是通过设定功能代号向Bnxxx说明要调用的服务功能的。

1.1.3.3          句柄

客户端的类名字可以设定为任意,客户端完成的任何功能,都需要调用Bpxxx(Ixxx)句柄,然后将请求发送到service。

1.1.4           Ixxx的作用

Ixxx规定的是服务端提供的接口,客户端要通过这些接口来向服务端请求,所以客户端保存的服务端标识都是Ixxx mXxx型的变量。客户端不可能直接调用Xxx类,因为它们在两个进程。

上面的描述有一点不合适,客户端有时也定义了Ixxx的接口,它一般是服务端对客户端的回调。所以Ixxx更准确的表达是本模块向外提供的接口,本模块既可以是服务端也可以是客户端。

下面我们以Camera为例进行说明。

1.1.5           DeathRecipient

当Binder服务端出现异常时,对客户端的通知。用户要实现DeathRecipient定义的binderDied虚函数,一般是对某些资源的释放。每个客户端都有自己的DeathRecipient对象,需要将这个对象注册到自己的服务端,代码如下defaultServiceManager()->getService(String16("media.camera"))->linkToDeath(mDeathNotifier),当服务端异常后,会掉用相应的binderDied通知。

当然如果客户端异常或者提前释放时,也要将这个DeathRecipient对象从服务端注销,代码如下defaultServiceManager()->getService(String16("media.camera"))->unlinkToDeath(mDeathNotifier)。

1.1.6           匿名服务

之前我们说到的服务都是要注册到defaultServiceManager的服务,还有很多服务没有进行注册,也可以使用。下面我们以Camera客户端Connect到CameraService后,CameraService要创建一个Client来服务Camera客户端,而这个Client其实就是一个未注册的Service。

sp<ICameraClient> cameraClient =interface_cast<ICameraClient>(data.readStrongBinder());

sp<ICamera> camera =connect(cameraClient, data.readInt32());

reply->writeStrongBinder(camera->asBinder());

首先获得客户端cameraClient,然后创建Client服务camera,然后通过writeStrongBinder将camera设为服务。

1.1.7           案例说明

以Camera为例说明,共三种关系。

ICameraService

客户端要请求Service完成拍照的功能,首先要让Service创建一个子项专门处理该客户端的请求,这个子项就是CameraService::Client。

该接口主要提供获得摄像头的个数、创建CameraService::Client等功能。如下图:

Android - Binder应用分析_第1张图片


ICamera

定义摄像头的功能接口,如设置参数、拍照、停止等操作。框架如下图:

Android - Binder应用分析_第2张图片


ICameraClient

客户端提供的回调函数接口,也可见,不一定Service才能够向外提供服务,客户端照样可以,框架如下图:

Android - Binder应用分析_第3张图片


1.1.8           重要代码

1.1.8.1          宏和函数

函数

功能说明

使用方法

 

 

 

DECLARE_META_INTERFACE

对I**的声明

声明接口的构造和析构函数

DECLARE_META_INTERFACE(Camera)等同于

static const android::String16 descriptor;

    static android::sp<ICamera> asInterface(const android::sp<android::IBinder>& obj);

    virtual const android::String16& getInterfaceDescriptor() const;

    ICamera ();                                                     \

    virtual ~ICamera ();

IMPLEMENT_META_INTERFACE

对Bp**的建立

1.       asInterface:新建Bp****

2.       构造和析构函数的实现

IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");等同于

const android::String16 ICamera::descriptor("android.hardware.ICamera");           

    const android::String16&ICamera::getInterfaceDescriptor() const {             

        return ICamera::descriptor;                                

    }                                                                   

    android::sp< ICamera> ICamera::asInterface(const android::sp<android::IBinder>& obj)                  

    {                                                                   

        android::sp<ICamera> intr;                                 

        if (obj != NULL) {                                              

            intr = static_cast< ICamera *>(obj->queryLocalInterface(ICamera::descriptor).get());              

            if (intr == NULL) {                                         

                intr = new BpCamera (obj);                         

            }                                                           

        }                                                              

        return intr;                                                    

    }                                                                   

    ICamera:: ICamera () { }                                    

    ICamera::~ ICamera () { }                                  






你可能感兴趣的:(Android - Binder应用分析)