Binder系列2 Binder概念及相关接口和类

Binder系列1 Binder总体设计思想中,主要从宏观上讲了 Binder 的总体设计思想和一些关键部分的设计细节,比如接收缓存管理,接收线程优化和线程池管理,接收包管理等.在系列2中会进一步细化 Binder 的概念和介绍实现 Binder 通信架构所用到的相关接口和类.

一 什么是Binder

简单地说,Binder 是 Android 平台上的一种跨进程通信技术。该技术最早并不是由 Google 公司提出的,它的前身是 Be Inc 公司开发的 OpenBinder,而且在 Palm 中也有应用。后来 OpenBinder 的作者 Dianne Hackborn 加入了 Google公司,并负责Android平台的开发工作,所以把这项技术也带进了 Android.

在 Android 的应用层次上,基本上已经没有过去的进程概念了。取而代之的都是 Activity,Service,BroadcastReceiver,和 ContentProvider 等各个组件.然而在实现层次,它毕竟还是要建构在一个个进程之上的。实际上,在 Android 内部,那些支撑应用程序的各个组件,往往会身处于不同的进程,那么应用程序的底层,必然会牵涉到大量的跨进程通信。为了保证通信的高效性,Android 提供了 Binder 机制.

 Binder 机制具有两层含义: 
1) 是一种跨进程通信手段(IPC,Inter-Process Communication)。 
2) 是一种远程过程调用手段(RPC,Remote Procedure Call)。

从实现的角度来说,Binder 的核心被实现成了一个 Linux 驱动程序,并运行于内核态。这样它才能具有强大的跨进程访问能力。

1.1 简述Binder的跨进程通信机制

为了理解 Binder,我们可以先画一张最简单的跨进程通信示意图:

初始篇001

这个很容易理解,不需赘言。到了 Android 平台上,IPC 机制就变成了 Binder 机制,情况类似,只不过为了便于说明问题,我们需要稍微调整一下示意图:

初始篇002

图中A侧的圆形块,表示“Binder代理方”也叫 Binder 引用,主要用于向远方发送语义,而B侧的方形块则表示“Binder响应方”也叫 Binder 实体,主要用于响应语义。需要说明的是,这种图形表示方法只是为了便于理解,个人觉得这种图形非常简便,所以在分析 Android 架构时,会经常使用这种表示法。

在后文中,我们可以看到,Binder 代理方对应于 C++ 层次的 BpBinder 对象,而 Binder 响应方则对应于 BBinder 对象。这两个对象在后文会详细阐述,此处不必太细究。

然而,上图的 Binder 代理方主要只负责了“传递信息”的数据传输工作,并没有起到“远程过程调用”的作用,如果要支持远程过程调用,我们还必须提供“接口代理方”和“接口实现体”。这样,我们的示意图就需要再调整一下,如下:

初始篇003

 

从图中可以看到,A进程并不直接和 BpBinder(Binder代理)打交道,而是通过调用 BpInterface(接口代理)的成员函数来完成远程调用的。此时,BpBinder 已经被聚合进 BpInterface 了,它在 BpInterface 内部完成了一切跨进程通信的机制。另一方面,与 BpInterface 相对的响应端实体就是 BnInterface(接口实现)了。需要注意的是,BnInterface 是继承于 BBinder 的,它并没有采用聚合的方式来包含一个 BBinder 对象,所以上图中B侧的 BnInterface 块和 BBinder 块的背景图案是相同的,BpBinder 是聚合进 BpInterface,而 BnInterface 是继承自 BBinder,了解和理解这一点非常重要。

        这样看来,对于远程调用的客户端而言,主要搞的就是两个东西,一个是 Binder 代理:BpBinder,另外一个就是“接口代理”:BpInterface。而服务端主要搞的则是“接口实现体”:BnInterface。因为 Binder 是一种跨进程通信机制,为了便于管理Binder服务,和便于 Client 获取 Binder 引用,Binder 机制就搞了一个专门的管理器来为通信两端牵线搭桥,这个管理器就是 SMgr。不过目前我们可以先放下 ServiceManager,在Binder系列3 ServiceManager启动和实现中会详细研究。

二 Binder相关接口和类

由于 Android 系统是分层次的系统,所以跨进程通信的 Binder,不但会在底层使用,也会在上层使用,所以需要提供 Java 和C++ 两个层次的支持。

2.1 Java层次的Binder元素

Java 层次里并没有我们前文图中所表示的 BpBinder、BpInterface、BBinder、BnInterface 等较低层次的概念,取而代之的是IBinder 接口、IInterface 等接口。Android 要求所有的 Binder 实体都必须实现 IBinder 接口,该接口的定义截选如下: 

frameworks/base/core/java/android/os/IBinder.java

public interface IBinder 
{
    . . . . . .
    public String getInterfaceDescriptor() throws RemoteException;
    public boolean pingBinder();
    public boolean isBinderAlive();
    public IInterface queryLocalInterface(String descriptor);
    public void dump(FileDescriptor fd, String[] args) throws RemoteException;
    public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException;
    public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
            @Nullable FileDescriptor err,
            @NonNull String[] args, @Nullable ShellCallback shellCallback,
            @NonNull ResultReceiver resultReceiver) throws RemoteException;

    public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)
    throws RemoteException;
    
    public interface DeathRecipient {
        public void binderDied();
    }
    public void linkToDeath(DeathRecipient recipient, int flags)throws RemoteException;
    public boolean unlinkToDeath(DeathRecipient recipient, int flags);
}

另外,不管是代理方还是实体方,都必须实现 IInterface 接口:

public interface IInterface
{
    /**
     * Retrieve the Binder object associated with this interface.
     * You must use this instead of a plain cast, so that proxy objects
     * can return the correct result.
     */
    public IBinder asBinder();
}

Java 层次中,与 Binder 相关的接口或类的继承关系如下:

初始篇004

 

在实际使用中,我们并不需要编写上图的 XXXXNative、XXXXProxy,它们会由 ADT 根据我们编写的 AIDL 脚本自动生成。用户只需继承 XXXXNative 编写一个具体的 XXXXService 即可,这个 XXXXService 就是远程通信的服务实体类,而 XXXXProxy 则是其对应的代理类。

        关于 Java 层次的 Binder 组件,我们就先说这么多,主要是先介绍一个大概。就研究跨进程通信而言,其实质内容基本上都是在 C++ 层次,Java 层次只是一个壳而已。以后我会写专文来打通 Java 层次和 C++ 层次,看看它们是如何通过 JNI 技术关联起来的。现在我们还是把注意力集中在 C++ 层次吧。

2.2 C++层次的Binder元素

在 C++ 层次,就能看到我们前文所说的 BpBinder 类和 BBinder 类了。这两个类都继承于 IBinder,IBinder 的定义截选如下:

frameworks/native/include/binder/IBinder.h

class IBinder : public virtual RefBase
{
public:
    .........

    IBinder();
  
    virtual sp<IInterface>  queryLocalInterface(const String16& descriptor);
    virtual const String16& getInterfaceDescriptor() const = 0;

    virtual bool            isBinderAlive() const = 0;
    virtual status_t        pingBinder() = 0;
    virtual status_t        dump(int fd, const Vector<String16>& args) = 0;
    static  status_t        shellCommand(const sp<IBinder>& target, int in, int out, int err,
                                         Vector<String16>& args, const sp<IShellCallback>& callback,
                                         const sp<IResultReceiver>& resultReceiver);

    virtual status_t        transact(   uint32_t code,
                                        const Parcel& data,
                                        Parcel* reply,
                                        uint32_t flags = 0) = 0;

   

    class DeathRecipient : public virtual RefBase {
    public:
        virtual void binderDied(const wp<IBinder>& who) = 0;
    };

   
    virtual status_t        linkToDeath(const sp<DeathRecipient>& recipient,
                                        void* cookie = NULL,
                              
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值