版权声明:转载请注明出处。作者:两仪织,博客地址:http://blog.csdn.net/u013894427 https://blog.csdn.net/u013894427/article/details/83870059
核心内容
Binder机制的核心实际上和Android中的Handler发送消息的机制很像,在Binder中负责发消息的是继承了BpInterface的子类,负责处理消息的是BnInterface的子类
发送消息的具体函数是
remote()->transact();
处理消息的具体函数是
onTransact();
基础知识
- BpInterface和BpBinder中的p表示的意思就是proxy,表示中间的调用和代理,不会具体实现功能
- BnInterface和BBinder中的n表示的意思就是native 是最终实现的地方
- BpBinder类由client来继承,当然,如果用不上的话,也可以不用继承
- 如果一个类如果想使用android中的智能指针,就必须继承或者间接继承RefBase类,比如client
继承关系
- 定义一个接口类IDemo,继承IInterface
- 定义一个BnDemoService类,继承BnInterface<IDemo>
- 定义一个BpDemoService类,继承BpInterface<IDemo>
- 定义一个DemoService类,继承BnDemoService,用来实现具体的函数
具体的实现
定义一个接口类IDemo,继承IInterface,里面只有一个函数
class IDemo :public IInterface
{
public:
virtual int getAge();
}
定义一个BnDemoService类,继承BnInterface<IDemo>
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);
}
定义一个BpDemoService类,继承BpInterface,<IDemo>
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();
}
}
定义一个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 );