C++ Binder机制学习

核心内容

Binder机制的核心实际上和Android中的Handler发送消息的机制很像,在Binder中负责发消息的是继承了BpInterface的子类,负责处理消息的是BnInterface的子类

发送消息的具体函数是

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

处理消息的具体函数是

status_t onTransact(uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)

基础知识

  • BpInterface和BpBinder中的p表示的意思就是proxy,表示中间的调用和代理,不会具体实现功能
  • BnInterface和BBinder中的n表示的意思就是native 是最终实现的地方
  • BpBinder类由client来继承,当然,如果用不上的话,也可以不用继承
  • 如果一个类想使用android中的智能指针,就必须继承或者间接继承RefBase类,比如client

继承关系

  • 定义一个接口类IDemo,继承IInterface
  • 定义一个BpDemoService类,继承BpInterface<IDemo>
  • 定义一个BnDemoService类,继承BnInterface<IDemo>
  • 定义一个DemoService类,继承BnDemoService,用来实现具体的函数

定义一个接口类IDemo,继承IInterface,里面只有一个函数

class IDemo :public IInterface
{
    public:
        virtual int getAge();
}

定义一个BpDemoService类,继承BpInterface

enum
{
	CUSTOM_CODE = IBinder::FIRST_CALL_TRANSACTION
};
class BpDemoService: public BnInterface<IDemo>
{
    public:
        BpDemoService(const sp<IBinder>& impl):BpInterface<IDemo> (impl){};
        virtual BOOL getAge()
		{
			Parcel data, reply;
		    data.writeInterfaceToken(IDemo::getInterfaceDescriptor());
		    remote()->transact(CUSTOM_CODE, data, &reply);
			return (BOOL)reply.readInt32();
		}
}

定义一个BnDemoService类,继承BnInterface

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

status_t BnDemoService::onTransact(uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)
{
	switch(code)
		{
			case CUSTOM_CODE:
				{
					CHECK_INTERFACE(IDemo,data,reply);
					int res = getAge();
					reply->writeInt32((int32_t)res);
					return NO_ERROR;
				}
				break;
			default:
	            break;
	   }
	return BBinder::onTransact(code, data, reply, flags);
}

定义一个Service类,继承BnDemoService

用来具体实现函数,最后记得别忘了调用IMPLEMENT_META_INTERFACE宏来进行注册

class DemoService : public BnDemoService,public BinderService<DemoService>
{
    public:
        int getAge();
}
IMPLEMENT_META_INTERFACE(DemoService, "demo.service");

调用顺序

  • 在client端调用的时候,首先获取ServiceManager
  • 然后创建一个binder用来装载service
  • 使用interface_cast()来获得对应的代理端
  • 通过代理端调用在service中实现的函数
sp < IServiceManager > sm = defaultServiceManager();
sp < IBinder > binder;
binder = sm->getService(String16("demo.service"));
sp<IDemo> m_pDemoService;
m_pDemoService = interface_cast<IDemo> (binder);
m_pDemoService->getAge();

重点函数

interface_cast()函数

作用是把从getService获取到的Binder强制转换为IInterface的子类,也就是定义了自己的那些接口的类
函数原型

template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

asInterface这个函数是IMPLEMENT_META_INTERFACE宏中进行定义的。具体可以参考

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
    const android::String16 I##INTERFACE::descriptor(NAME);             \
    const android::String16&                                            \
            I##INTERFACE::getInterfaceDescriptor() const {              \
        return I##INTERFACE::descriptor;                                \
    }                                                                   \
    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
            const android::sp<android::IBinder>& obj)                   \
    {                                                                   \
        android::sp<I##INTERFACE> intr;                                 \
        if (obj != NULL) {                                              \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == NULL) {                                         \
                intr = new Bp##INTERFACE(obj);/* IMPORTENT */           \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }         

也就是说interface_cast函数最后返回的实际上是new BpDemoService(binder);

remote()->transact()函数

位置是在代理类中调用的,用来远程给onTransact函数发送消息和数据的,类似于handler.sendMessage()
函数原型

status_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

onTransact()函数

这个函数的位置是在实现类(实现BnInterface)中的,相当于hander中的handleMessage函数

函数原型

virtual status_t onTransact(uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags= 0 );
  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值