Binder原理之BpBinder,BnBinder以及IInterface介绍

一:Binder机制介绍

Binder机制是Android系统提供的跨进程通讯机制。Client进程希望可以与Server进程沟通,但由于是跨进程,所以需要借助Binder驱动进程通信。

Binder由以下模块组成:

    *  Binder驱动

    *  Binder Server端 - Server进程

    *  Binder Client端 - Client进程

    *  ServiceManager - 管理者

Binder的通信模型如下所示:

 二:创建Service模型

如果要创建一个Service,需要Server端继承BnInterface, Client端继承BpInterface。具体可用下图表示:

扫描二维码关注公众号,回复: 16382777 查看本文章

可在如下文件中找到关于Bn, Bp相关的声明

frameworks/native/libs/binder/include/binder/IInterface.h

frameworks/native/libs/binder/include/binder/IBinder.h

 具体代码如下

frameworks/native/libs/binder/include/binder/IInterface.h
class IInterface : public virtual RefBase
{
public:
            IInterface();
            static sp<IBinder>  asBinder(const IInterface*);
            static sp<IBinder>  asBinder(const sp<IInterface>&);

protected:
    virtual                     ~IInterface();
    virtual IBinder*            onAsBinder() = 0;
};
-----------------------------------------------------------
class BnInterface : public INTERFACE, public BBinder
{
public:
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;

protected:
    typedef INTERFACE           BaseInterface;
    virtual IBinder*            onAsBinder();
};

frameworks/native/libs/binder/include/binder/Binder.h
class BBinder : public IBinder
{
public:
                        BBinder();

    virtual const String16& getInterfaceDescriptor() const;
    virtual bool        isBinderAlive() const;
    virtual status_t    pingBinder();
...
};
frameworks/native/libs/binder/include/binder/IBinder.h
class [[clang::lto_visibility_public]] IBinder : public virtual RefBase
{
public:
    enum {
        FIRST_CALL_TRANSACTION = 0x00000001,
        LAST_CALL_TRANSACTION = 0x00ffffff,
...
};
-------------------------------------------------------------------
class BpInterface : public INTERFACE, public BpRefBase
{
public:
    explicit                    BpInterface(const sp<IBinder>& remote);

protected:
    typedef INTERFACE           BaseInterface;
    virtual IBinder*            onAsBinder();
};

frameworks/native/libs/binder/include/binder/Binder.h
class BpRefBase : public virtual RefBase
{
protected:
    explicit                BpRefBase(const sp<IBinder>& o);
    virtual                 ~BpRefBase();
    virtual void            onFirstRef();
    virtual void            onLastStrongRef(const void* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);

    inline IBinder* remote() const { return mRemote; }//返回的是BpBinder
    inline sp<IBinder> remoteStrong() const { return sp<IBinder>::fromExisting(mRemote); ...

 三:进程间传递数据的载体 - Parcel

Parcel代码位于如下目录,Parcel用于传递进程间的数据。不管是Client发送数据给Server,还是Server发送数据给Client,都是通过Parcel进行传递。

frameworks/native/include/binder/Parcel.h

frameworks/native/include/binder/Parcel.cpp

write相关接口:

    status_t            write(const void* data, size_t len);
    status_t            writeInt32(int32_t val);
    status_t            writeUint32(uint32_t val);
    status_t            writeInt64(int64_t val);
    status_t            writeUint64(uint64_t val);
    status_t            writeFloat(float val);
    status_t            writeDouble(double val);
    status_t            writeStrongBinder(const sp<IBinder>& val);
    status_t            writeInt32Array(size_t len, const int32_t *val);
    status_t            writeByteArray(size_t len, const uint8_t *val);
    status_t            writeBool(bool val);
    status_t            writeChar(char16_t val);
    status_t            writeByte(int8_t val);
......

 read相关接口:

    status_t            read(void* outData, size_t len) const;
    const void*         readInplace(size_t len) const;
    int32_t             readInt32() const;
    status_t            readInt32(int32_t *pArg) const;
    uint32_t            readUint32() const;
    status_t            readUint32(uint32_t *pArg) const;
    int64_t             readInt64() const;
    status_t            readInt64(int64_t *pArg) const;
    uint64_t            readUint64() const;
    status_t            readUint64(uint64_t *pArg) const;
    float               readFloat() const;
    status_t            readFloat(float *pArg) const;
    double              readDouble() const;
    status_t            readDouble(double *pArg) const;
    bool                readBool() const;
    status_t            readBool(bool *pArg) const;
    char16_t            readChar() const;
    status_t            readChar(char16_t *pArg) const;
    int8_t              readByte() const;
    status_t            readByte(int8_t *pArg) const;
......

举个例子,在native service中是如何通过Parcel传递数据的,如下所示,都是通过Parcel进行传递。

class BpCustomizeManagerService : public BpInterface<ICustomizeManagerService>
{
public:
    explicit BpCustomizeManagerService (const sp<IBinder>& impl)
      : BpInterface <ICustomizeManagerService>(impl)
    {
        ALOGD("create Service \n");
    }

    int customeize(int size){
        Parcel data, reply;
        data.writeInterfaceToken(ICustomizeManagerService::getInterfaceDescriptor());
        data.writeInt32(size);
        remote()->transact(CUSTOMIZE, data, &reply);
        return reply.readInt32();
    }
};

status_t BnCustomizeManagerService ::onTransact(uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags){
    switch (code)
    {
        case CUSTOMIZE:
        {
            CHECK_INTERFACE(ICustomizeManagerService, data, reply);
            int size = data.readInt32();
            int ret = customeize(size);
            //函数返回值从Server传递给Client
            reply->writeInt32();
            return NO_ERROR;
        }
...
};

猜你喜欢

转载自blog.csdn.net/weixin_41028555/article/details/130379626