Binder 简介
Binder是用在Android系统中的一个进程间通信(IPC)机制,使用C/S 服务端和客户端通过Binder进行跨进程的数据交换;Binder继承自IBinder接口,因此IBinder接口最重要的一个方法是transact,所以虽然Android为了减少开发者开发工作量,采用了代理模式封装了一个复杂的Binder架构,但是其本质都是从源进程传递数据给目标进程;然后目标进程处理完后再把数据回传给源进程
Binder 的数据传输流程如下:
- client 端发送的流程
- client 端创建得到一个 BpxxService,会调用BpxxService 实现的接口函数(比如 helloworld);它会将str参数打包到Parcel 对象中,然后调用remote()->transact(xxx)
- remote() 是在BpXXXService的父类 BpRefBase 中实现的,返回的就是一个BpBinder,实际上调用的就是BpBinder 的transact()函数
- BpBinder 的transact实现,就是直接通过IPCThreadState::self()->transact()发送数据
- service 端接收Client 端的请求
- 通过IPCThreadState接收到client的请求后,首先会调用BBinder的transact方法
- BBinder的transact方法又会调用子类实现的虚拟方法onTransact,这个虚拟方法是在BnXXXService中实现的
- onTransact方法,会通过传递进来的参数来判断,需要调用IXXXService中的那个方法,示例中只有一个helloWorld方法
- 直接调用helloWorld,就会找到它的真正实现,也就是BnXXXService的子类XXXService中的helloWorld方法
总结一下:BpBinder并不在继承关系当中,它只是一个打包数据,并通过IPCThreadState::self()->transact()方法发送出去,而BBinder和BnXXXService的作用,就是接收IPCThreadState传递过来的信息,解包数据并调用XXXService真正的实现
Binder 源代码路径:/frameworks/native/libs/binder
Binder 类的继承关系图如下:
interface_binder.jpg
基础 Native层 Binder demo
新建IMyService.h 和 IMyService.cpp,其中主要定义BnMyService 和 BpMyService类(p表示 proxy 是客户端使用的对象,n 表示 native,是server 端使用的对象)
IMyService.h
#ifdef _MYSERVICE_H
#define _MYSERVICE_H
#include <utils/RefBase.h>
#include <utils/Error.h>
#include <utils/String16.h>
#include <binder/IIterface.h>
#include <binder/Parcel.h>
namespace android {
class IMyService:public IInterface {
public:
DECLARE_META_INTERFACE(MyService);
virtual void demoInterface() = 0;
}
enum {
DEMOINTERFACE = 1;
};
class BpMyService:public BpInterface<IMyService> {
public:
explicit BpMyService(const sp<IBinder>& impl);
virtual ~BpMyService();
virtual void demoInterface();
};
class BnMyService: public BnInterface<IMyService> {
public:
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
inline BnMyService() {};
virtual void demoInterface();
};
}
#endif
IMyService.cpp
#define LOG_TAG "IMyService"
namespace android {
IMPLEMENT_META_INTERFACE(MyService,"android.demo.IMyService");
BpMyService::BpMyService(const sp<IBinder>& impl):BpInterface<IMyService>(impl) {
}
void BpMyService::demoInterface() {
Parcel data, reply;
data.writeInterfaceToken(IMyService::getInterfaceDescriptor());
remote()->transact(DEMOINTERFACE, data, &reply);
std::cout << "get num from BnMyService" << reply.readInt32() << std::endl;
}
status_t BnMyService::onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags) {
flags = 0;
switch(code) {
case DEMOINTERFACE:
cout << "BnMyService:: onTransact... " << endl;
CHECK_INTERFACE(IMyService, data, reply);
demoInterface();
reply->writeInt32(2015);
return NO_ERROR;
break;
default:
break;
}
return NO_ERROR;
}
void BnMyService::demoInterface() {
cout << "BnMyService:: demoInterface" << endl;
}
}
定义的 BpMyService 类和 BnMyService类都继承了 IMyService类,继承方式采用android binder 定义的模板:
class BpMyService: public BpInterface<IMyService>
class BnMyService: public BnInterface<IMyService>
BpInterface 是定义和实例化后的代码如下:
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
explicit BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
实例化之后的类:
class BpInterface : public IMyService, public BpRefBase
{
public:
explicit BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
BpMyService::demoInterface() 中使用的remote() 函数就是在 BpRefBase中定义的,是一个IBinder 类型的指针,是从ServiceManager getService 获取到的,本质上就是一个BpBinder对象
IBinder* const mRemote;
在定义 IMyService 类中,还有两个重要的宏:
DECLARE_META_INTERFACE(IMyService);
IMPLEMENT_META_INTERFACE(INTERFACE, NAME) ;
宏展开后的形式:
#define DECLARE_META_INTERFACE()
static const String16 descriptor;
static android::sp<IMyService> asInterface(sp<:IBinder>& obj);
virtual const String16& getInterfaceDescriptor() const;
IMyService();
virtual ~IMyService();
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)
const String16 IMyService::descriptor(NAME);
const String16&
IMyService::getInterfaceDescriptor() const {
return IMyService::descriptor;
}
sp<IMyService> IMyService::asInterface(
const sp<IBinder>& obj)
{
sp<IMyService> intr;
if (obj != NULL) {
intr = static_cast<IMyService*>(
obj->queryLocalInterface(
IMyService::descriptor).get());
if (intr == NULL) {
intr = new BpMyService(obj);
}
}
return intr;
}
IMyService::IMyService() { }
IMyService::~IMyService() { }
这里用这两个宏简化了 IMyService 类的定义,其中有两个重要的成员
- getInterfaceDescriptor 可以获取到binder 传输需要使用的 Token Descriptor
- asInterface 函数返回BpMyService 对象
Binder 中关键类解析
IBinder
IBinder也是一个抽象类,它包括了localBinder(), remoteBinder()和transact()等非常重要的接口;IBinder有两个直接子类类:BpBinder和BBinder
class IBinder : public virtual RefBase {
/**
* Check if this IBinder implements the interface named by
* @a descriptor. If it does, the base pointer to it is returned,
* which you can safely static_cast<> to the concrete C++ interface.
*/
virtual sp<IInterface> queryLocalInterface(const String16& descriptor);
......
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0) = 0;
.....
virtual BBinder* localBinder();
virtual BpBinder* remoteBinder();
}
BpBinder和BBinder
BpBinder 对象
BpBinder:是Binder代理类,通过remoteBinder()可以获取BpBinder对象;
BpBinder的事务接口transact()会调用 IPCThreadState的transact(),进而实现与Binder驱动的事务交互
BpBinder中有一个mHandle句柄成员,用于保存server 位于Binder 驱动中 Binder 引用的描述,Handle = 0 就是ServiceManager 的handle
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
BpBinder* BpBinder::remoteBinder()
{
return this;
}
inline int32_t handle() const { return mHandle; }
BBinder对象
BBinder:Servier 端的Binder 对象,通过localBinder()可以获取BBinder对象,当Server收到请求之后,会调用BBinder的onTransact()函数进行处理。而不同的Server会重载onTransact()函数,从而可以根据各自的情况对事务进行处理
BBinder* BBinder::localBinder()
{
return this;
}
class BBinder : public IBinder
{
public:
BBinder();
virtual const String16& getInterfaceDescriptor() const;
virtual bool isBinderAlive() const;
virtual status_t pingBinder();
...
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
...
virtual BBinder* localBinder();
protected:
virtual ~BBinder();
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
private:
BBinder(const BBinder& o);
...
};
RefBase和BpRefBase
RefBase:使用andoid 智能指针必须继承的基础类,包含了智能指针的引用计数
BpRefBase:
BpRefBase继承于RefBase,它有一个IBinder*类型的成员mRemote,同时提供了获取该mRemote的方法。实际上,该mRemote就是BpBinder对象
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() { return mRemote; }
inline IBinder* remote() const { return mRemote; }
private:
BpRefBase(const BpRefBase& o);
BpRefBase& operator=(const BpRefBase& o);
IBinder* const mRemote;
RefBase::weakref_type* mRefs;
std::atomic<int32_t> mState;
};
IInterface 和 interface_cast
IInterface 定义在frameworks/native/include/binder/IInterface.h中,和RefBase类似,它也是一个公共父类,IInterface中声明了asBinder()方法,用于获取对象的IBinder对象。
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;
};
onAsBinder函数在 IInterface 的父类 BpMyService 和 BnMyService 中实现,具体是在 BnInterface 和 BpInterface 的模板中实现:
interface_cast 是一个模板函数,本质上就是调用 asInterface 接口,在IMyService 的实现中,返回就是BpMyService的对象;
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
IMyService.cpp
sp<IMyService> IMyService::asInterface(
const sp<IBinder>& obj)
{
sp<IMyService> intr;
if (obj != NULL) {
intr = static_cast<IMyService*>(
obj->queryLocalInterface(
IMyService::descriptor).get());
if (intr == NULL) {
intr = new BpMyService(obj);
}
}
return intr;
}
BpInterface 和 BnInterface
-
BpInterface:它定义在frameworks/native/include/binder/IInterface.h中;BpInterface是一个模板类,同时继承了BpRefBase和INTERFACE,这里的INTERFACE是模板,像IServiceManager,IMediaPlayerService,IMyService
-
BnInterface:它定义在frameworks/native/include/binder/IInterface.h中,和BpInterface类似,BnInterface也是一个模板类,它同时继承了BBinder和INTERFACE;像BnServiceManager,BnMediaPlayerService,BnMyService
网友评论