Android Binder机制(三) Binder相关的接口和类
Android Binder机制(三) Binder相关的接口和类
前言
前面的篇章Android Binder机制(二) Binder中的数据结构对我们要强攻的Binder机制中将要牵涉到的数据结构,包括应用层的和内核层的做了非常详细的讲解和阐述。本篇幅重点要突破的是Binder机制中相关的接口和类,我们知道Android的绝大部分跨进程通信机制都是基于Binder的,正所谓做戏得全套,Binder也不列外,这种机制不但会在底层C++的世界使用,也会在上层Java的世界使用,所以必须提供Java和C++两个层次的支持。当然这些Android的妈咪谷歌都为我们考虑到了。
1. Java层次的Binder接口和类
Java层级的Binder相关的接口和类并不是很多,因为Binder其实大部分的重头戏都是在C++层和内核层,常见的接口和类有IBinder接口、IInterface接口,Binder类,BinderProxy类等。
1.1 IBinder
Android要求所有的Binder实体都必须实现IBinder接口,其文件在Android源码的路径是frameworks/base/core/java/android/os/IBinder.java,该接口的定义截选如下:
public interface IBinder {
...
public String getInterfaceDescriptor() throws RemoteException;
public boolean pingBinder();
public boolean isBinderAlive();
public IInterface queryLocalInterface(String descriptor);
public void dump(FileDescriptor fd, String[] args) throws RemoteException;
public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException;
public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
String[] args, ResultReceiver resultReceiver) throws RemoteException;
public boolean transact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException;
public interface DeathRecipient {
public void binderDied();
}
public void linkToDeath(DeathRecipient recipient, int flags)
throws RemoteException;
public boolean unlinkToDeath(DeathRecipient recipient, int flags);
}
1.2 IInterface
IInterface接口比较简单,其源码路径为仅仅单单定义了一个方法,不管是服务端还是客户端都需要实现该接口
public interface IInterface {
IBinder asBinder();
}
1.3 BinderProxy
BinderProxy是IBinder的子类,客户端进程持有关联的服务的的BinderProxy对象从而完成相关的远程服务调用,其底层相对应的C++层的BpBinder后续会介绍
final class BinderProxy implements IBinder {
public native boolean pingBinder();
public native boolean isBinderAlive();
public IInterface queryLocalInterface(String descriptor) {
return null;
}
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }
return transactNative(code, data, reply, flags);
}
public native String getInterfaceDescriptor() throws RemoteException;
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
...
}
1.4 Binder
Binder也是IBinder的子类,Java层提供服务的Server进程持有一个Binder对象从而完成跨进程间通信
public class Binder implements IBinder {
public String getInterfaceDescriptor() {
return mDescriptor;
}
public IInterface queryLocalInterface(String descriptor) {
if (mDescriptor.equals(descriptor)) {
return mOwner;
}
return null;
}
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
...
}
public final boolean transact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
if (false) Log.v("Binder", "Transact: " + code + " to " + this);
if (data != null) {
data.setDataPosition(0);
}
boolean r = onTransact(code, data, reply, flags);
if (reply != null) {
reply.setDataPosition(0);
}
return r;
}
}
Java层次中,与Binder相关的接口或类的继承关系如下:
在实际开发使用中,我们并不需要编写上图的XXXXNative、XXXXProxy,它们会由ADT根据我们编写的aidl脚本自动生成。但是最好能掌握手撕什么相关的类实现,这样对于更好的理解和掌握BInd非常有帮助的。用户只需继承XXXXNative编写一个具体的XXXXService即可,这个XXXXService就是远程通信的服务实体类,而XXXXProxy则是其对应的代理类。
关于Java层次的binder组件,我们就先说这么多,主要是先介绍一个大概。就研究跨进程通信而言,其实质内容基本上都在C++层次,Java层次只是一个壳而已。以后我会写专文来打通Java层次和C++层次,看看它们是如何通过JNI技术关联起来的。现在我们还是把注意力集中在C++层次吧。
2. C++层次的相关接口和类
在C++层次,就能看到各种关于Binder博客中经常反复肯定会被提到的BpBinder类和BBinder了,这两个类都继承于IBinder。当然还有IInterface,BpInterface,BnInterface,BpRefBase,ProcessState ,IPCThreadState ,下面我们来分别进行简单的介绍,在正式介绍前先奉上一关于上述几个接口和类之前的关系图,这就好比相亲之前得让介绍人先给个对方的照片,看过以后才能确定是否有进一步发展的空间不是!
2.1 IBinder
它定义在frameworks/native/include/binder/IBinder.h中。IBinder也是一个抽象出来的类,它包括了localBinder(), remoteBinder()和transact()等非常重要的接口。IBinder有两个直接子类类:BpBinder和BBinder。
class IBinder : public virtual RefBase
{
public:
...
IBinder();
virtual sp<IInterface> queryLocalInterface(const String16& descriptor);
virtual const String16& getInterfaceDescriptor() const = 0;
virtual bool isBinderAlive() const = 0;
virtual status_t pingBinder() = 0;
virtual status_t dump(int fd, const Vector<String16>& args) = 0;
static status_t shellCommand(const sp<IBinder>& target, int in, int out, int err,
Vector<String16>& args,
const sp<IResultReceiver>& resultReceiver);
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0) = 0;
class DeathRecipient : public virtual RefBase
{
public:
virtual void binderDied(const wp<IBinder>& who) = 0;
};
virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0) = 0;
virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = NULL) = 0;
virtual bool checkSubclass(const void* subclassID) const;
typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie);
virtual void attachObject( const void* objectID,
void* object,
void* cleanupCookie,
object_cleanup_func func) = 0;
virtual void* findObject(const void* objectID) const = 0;
virtual void detachObject(const void* objectID) = 0;
virtual BBinder* localBinder();
virtual BpBinder* remoteBinder();
protected:
virtual ~IBinder();
private:
};
2.2 BpBinder和BBinder
BpBinder和BBinder是相互对应的,可以算是一对兄弟组合,下面分别来介绍一下:
(1). BpBinder:是Binder代理类。通过remoteBinder()可以获取BpBinder对象;而且,对于C++层而言,它相当于一个远程Binder。BpBinder的事务接口transact()会调用IPCThreadState的transact(),进而实现与Binder驱动的事务交互。此外,BpBinder中有一个mHandle句柄成员,它用来保存Server位于Binder驱动中的"Binder引用的描述"。句柄0是ServiceManager的句柄。
class BpBinder : public IBinder
{
public:
BpBinder(int32_t handle);
inline int32_t handle() const { return mHandle; }
...
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
...
virtual BpBinder* remoteBinder();
private:
const int32_t mHandle;
...
}
(2).BBinder:是本地Binder。通过localBinder()可以获取BBinder对象。当Server收到请求之后,会调用BBinder的onTransact()函数进行处理。而不同的Server会重载onTransact()函数,从而可以根据各自的情况对事务进行处理。
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);
...
};
2.3 RefBase和BpRefBase
如果说BpBinder和BBinder是兄弟组合,那么RefBase和BpRefBase就是父子组合了,下面分别就两位来一个全方位的展示:
(1).RefBase:它定义在system/core/include/utils/RefBase.h中。RefBase是一个公共父类,它声明了许多常用的接口。包括增加引用计数,获取引用计数,新增对象的弱引用等接口,其中比较重要的方法是onFirstRef(),在Android的Native世界里面你会惊奇的发现许多C++的初始化工作都是在onFirstRef()里面执行的,不信可以搜搜试试。
class RefBase
{
public:
void incStrong(const void* id) const;
void decStrong(const void* id) const;
void forceIncStrong(const void* id) const;
int32_t getStrongCount() const;
class weakref_type
{
public:
RefBase* refBase() const;
void incWeak(const void* id);
void decWeak(const void* id);
...
};
...
protected:
RefBase();
virtual ~RefBase();
...
virtual void onFirstRef();
...
};
(2).BpRefBase:它定义在frameworks/native/include/binder/Binder.h中。BpRefBase继承于RefBase,它有一个IBinder*类型的成员mRemote,同时提供了获取该mRemote的方法。实际上,该mRemote就是BpBinder对象。
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);
inline IBinder* remote() { return mRemote; }
inline IBinder* remote() const { return mRemote; }
private:
BpRefBase(const BpRefBase& o);
BpRefBase& operator=(const BpRefBase& o);
IBinder* const mRemote;//这就是那个很重要的mRemote
RefBase::weakref_type* mRefs;
std::atomic<int32_t> mState;
};
推荐阅读
-
Android Binder机制(三) Binder相关的接口和类
-
Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路
-
Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析
-
Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
-
Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路
-
Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
-
Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析
-
Android Binder机制(一) Binder的设计和框架