个人对binder的学习

class IInterface : public virtual RefBase
{
public:
            IInterface();
            sp<IBinder>         asBinder();IBinder是远程对象的基本接口
            sp<const IBinder>   asBinder() const;
           
protected:
    virtual                     ~IInterface();
    virtual IBinder*            onAsBinder() = 0;
};
asBinder是封装了onAsBinder的,而onAsBinder是纯虚函数,
RefBase 类作为基类起引用计数作用。

IBinder 主要作用函数:transact():
virtual status_t        transact(   uint32_t code,
                                        const Parcel& data,
                                        Parcel* reply,
                                        uint32_t flags = 0) = 0;

class IMediaRecorder: public IInterface 定义一些抽象方法。

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
                                BpInterface(const sp<IBinder>& remote);

protected:
    virtual IBinder*            onAsBinder();
};

则BpInterface<IMediaRecorder> 展开来即:
class BpInterface :public IMediaRecorder ,public BpRefBase
{

  public:
                                BpInterface(const sp<IBinder>& remote);

protected:
    virtual IBinder*            onAsBinder();
}

class BnMediaRecorder: public BnInterface<IMediaRecorder>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

下面看onTransact的实现:
   switch(code) {
        case RELEASE: {
            LOGV("RELEASE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            reply->writeInt32(release());
            return NO_ERROR;
        } break;

#define CHECK_INTERFACE(interface, data, reply)                         \
    if (!data.checkInterface(this)) { return PERMISSION_DENIED; }       \


发送的数据是Parcel,Parcel是一种一般的缓冲区,除了有数据外还带有一些描述它内容的元数据,
元数据用于管理IBinder对象的引用,这样就能在缓冲区从一个进程移动到另一个进程时保存这些引用.

系统为每个进程维护一个存放交互线程的线程池。这些交互线程用于派送所有从另外进程发来的远程服务调用,IBinder在两个进程中

传递。
例如:当一个IPC从进程A发到进程B,A中那个发出调用的线程(这个应该不在线程池中)就阻塞在transact()中了。进程B中的交互

线程池中的一个线程接收了这个调用,它调用Binder.onTransact(),完成后用一个Parcel来做为结果返回,B线程接收这个Parcel之

后认为远程调用结束。

然后进程A中的那个等待的线程在收到返回的Parcel后得以继续执行。实际上,另一个进程看起来就像是当前进程的一个线程,但不

是当前进程创建的。
进程B中的交互线程池中的一个线程接收了这个调用,它调用Binder.onTransact(),完成后用一个Parcel来做为结果返回。然后进程

A中的那个等待的线程在收到返回的Parcel后得以继续执行。实际上,另一个进程看起来就像是当前进程的一个线程,但不是当前进

程创建的。


Binder机制还支持进程间的递归调用。例如,进程A执行自己的IBinder的transact()调用进程B的Binder,而进程B在其

Binder.onTransact()中又用transact()向进程A发起调用,那么进程A在等待它发出的调用返回的同时,还会用Binder.onTransact

()响应进程B的transact()。总之Binder造成的结果就是让我们感觉到跨进程的调用与进程内的调用没什么区别。

要实现IBinder来支持远程调用,应从Binder类派生一个类。Binder实现了IBinder接口。但是一般不需要直接实现此类,而是跟据你

的需要由开发包中的工具生成,这个工具叫aidi。你通过aidi语言定义远程对象的方法,然后用aidi工具生成Binder的派生类,然后

就可使用之。然而,可是,但是,当然,你也可以直接从Binder类派生以实现自定义的RPC调用,或只是实例化一个原始的Binder对象

直接作为进程间共享的令牌来使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值