Binder运用

Binder应用

关于Binder原理这里不做介绍了,可以参看Android技术内幕,但是关于Binder应用讲解的很详细的不多,因我在做一个移植的项目,与media类似,故研究了一下media,特别对其中的如何实现客户端、服务端才能通过Binder通信进行学习,总结如下:

1、基于接口编程,这是编程的趋势,好处实在太多

2、使得接口支持Binder,需要2步:

2.1定义接口,继承IInterface,并添加DECLARE_META_INTERFACE,并定义服务端接口,如下所示:

class IClient: public IInterface
{
public:
    DECLARE_META_INTERFACE(Client);
    virtual long  Add(long a,long b) = 0;
};

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

2.2 实现客户端和服务端

#define LOG_TAG "IClient"
//#define LOG_NDEBUG 0
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>

#include <IClient.h>

namespace android {

enum {
    ADD = IBinder::FIRST_CALL_TRANSACTION
};

class BpClient : public BpInterface<IClient>
{
public:
    BpClient(const sp<IBinder>& impl)
        : BpInterface<IClient>(impl)
    {
    }
    virtual long Add(long a,long b)
    {
        Parcel data,reply;
        data.writeInterfaceToken(IClient::getInterfaceDescriptor());
        data.writeInt32(a);
        data.writeInt32(b);
        remote()->transact(ADD,data,&reply);
        return reply.readInt32();
    }
   };

IMPLEMENT_META_INTERFACE(Client, "android.test.IClient");

// ----------------------------------

status_t BnClient::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        case ADD:
        {
           CHECK_INTERFACE(IClient, data, reply);
           reply->writeInt32(Add(data.readInt32(),data.readInt32()));
           return NO_ERROR;
        };
        break;
      
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}
}; // namespace android

3、最后在服务端实现具体类,继承BnClient