本文以Audio系统为例,基于Android 7.1
IInterface.h是C++层Binder通信的规范定制者, 客户端和服务端都要包含该头文件。
IInterface.h中提供了C++层Binder通信必要的工具。
客户端需要继承BpInterface 和IInterface,这个是个模板类,作用其实是使客户端对象继承自模板对象,如下:
//frameworks/native/include/binder/IInterface.h
//IInterface 中定义了对Binder的转换操作
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;
};
//BpInterface
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase //**BpRefBase 中有个remote()函数,
//直接指向服务端Bind而对象
{
public:
//remote使服务端Binder对象
BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
BpRefBase
BpRefBase 继承自RefBase,所以在首次引用的时候会调用onFirstRef方法
//frameworks/native/include/binder/Binder.h
class BpRefBase : public virtual RefBase
{
protected:
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);
//remote()函数直接使用,就是代表了服务端对象
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;
};
//构造实现
BpRefBase::BpRefBase(const sp<IBinder>& o)
//mRemote来自子类的传递
: mRemote(o.get()), mRefs(NULL), mState(0)
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
if (mRemote) {
mRemote->incStrong(this); // Removed on first IncStrong().
mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
}
}
服务端要继承BnInterface ,这个是个模板类,作用其实是使服务端对象继承自模板对象,如下:
//frameworks/native/include/binder/IInterface.h
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const;
protected:
virtual IBinder* onAsBinder();
};
Android提供的这两个宏是方便Binder接口的统一实现
需要以‘I’开头加上传入的接口变量来做声明/实现
DECLARE_META_INTERFACE
: 声明接口构造#define DECLARE_META_INTERFACE(INTERFACE) \
static const android::String16 descriptor; \
static android::sp asInterface( \
const android::sp& obj); \
virtual const android::String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE(); \
IMPLEMENT_META_INTERFACE
:#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
//descriptor是客户端和服务端的对接标识符,以传入的NAME作为初始化内容
const android::String16 I##INTERFACE::descriptor(NAME); \
const android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
//服务端的Binder对象是通过接口的asInterface传入的,所以在找服务端接口的时候,可以使用
//I##INTERFACE::asInterface来查找
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) { \
//创建客户端对象,传入服务端Binder对象
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
---------------------------------------------------------------------------------------
//一个方便的函数,将Binder对象转换为对应的客户端接口
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);//也是调用对应模板的asInterface方法的
}
//frameworks/av/include/media/IAudioFlinger.h
class IAudioFlinger : public IInterface
{
public:
DECLARE_META_INTERFACE(AudioFlinger);//声明宏
}
//服务端实现接口的规范
class BnAudioFlinger : public BnInterface<IAudioFlinger>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
//frameworks/av/media/libmedia/IAudioFlinger.cpp
class BpAudioFlinger : public BpInterface<IAudioFlinger>
{
public:
BpAudioFlinger(const sp<IBinder>& impl)
: BpInterface<IAudioFlinger>(impl)//这里的构造中的Binder对象是在上面的
//IMPLEMENT_META_INTERFACE宏中传入的
{
}
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
}
获取IAudioFlinger服务端的例子:
//frameworks/av/media/libmedia/AudioSystem.cpp
const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
{
sp<IAudioFlinger> af;
sp<AudioFlingerClient> afc;
{
Mutex::Autolock _l(gLock);
if (gAudioFlinger == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
//获取AudioFlinger Binder对象
binder = sm->getService(String16("media.audio_flinger"));
if (binder != 0)
break;
...
} while (true);
...
//转化为IAudioFlinger 接口,作为服务端代理
gAudioFlinger = interface_cast<IAudioFlinger>(binder);
...
}
af = gAudioFlinger;
}
...
return af;
}
客户端信息总结:
IAudioFlinger
BpAudioFlinger
android.media.IAudioFlinger
AudioFlinger
AudioFlinger
//frameworks/av/services/audioflinger/AudioFlinger.h
class AudioFlinger :
public BinderService<AudioFlinger>, //这个接口会将AudioFlinger 注册到ServiceManager中
public BnAudioFlinger //继承自BnInterface
{
friend class BinderService<AudioFlinger>; // for AudioFlinger()
public:
//服务端在ServiceManager注册的时候的服务账号,客户端用这个账号从ServiceManager中获取服务端Binder对象。
static const char* getServiceName() ANDROID_API { return "media.audio_flinger"; }
}
服务端信息总结
IAudioFlinger
(和客户端对应,这样才转换为客户端接口IAudioFlinger)AudioFlinger
media.audio_flinger
inerface_cast
接口或者I##INTERFACE::asInterface
转换为客户端接口I##INTERFACE,在客户端直接使用的体现是remote()函数;