Android Binder入门指南之Binder相关的接口和类

前言

   前面的篇章Android Binder机制(二) Binder中的数据结构对我们要攀登的Binder机制中将要牵涉到的数据结构(包括应用层的和内核层的)做了非常详细的讲解和阐述。本篇幅重点要突破的是Binder机制中相关的接口和类,我们知道Android的绝大部分跨进程通信机制都是基于Binder的,正所谓做戏得全套,Binder也不列外,这种机制不但会在底层C++的世界使用,也会在上层Java的世界使用,所以必须提供Java和C++两个层次的支持。当然这些Android的妈咪谷歌都为我们考虑到了。
   在正式开始正文介绍前附上本篇相关代码的所在文件的路径。

frameworks/base/core/java/android/os/IBinder.javaframeworks/base/core/java/android/os/Binder.javaframeworks/base/core/java/android/os/IInterface.javaframeworks/native/include/binder/IBinder.hframeworks/native/libs/binder/Binder.cppframeworks/native/include/binder/Binder.hframeworks/native/include/binder/BpBinder.hframeworks/native/libs/binder/BpBinder.cppsystem/core/include/utils/RefBase.hframeworks/native/include/binder/IInterface.hframeworks/native/include/binder/ProcessState.hframeworks/native/libs/binder/ProcessState.cppframeworks/native/include/binder/IPCThreadState.hframeworks/native/libs/binder/IPCThreadState.cpp

注意:本文是基于Android 7.1版本进行介绍的!

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;};

2.4 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;};

2.5 BpInterface和BnInterface

(1).BpInterface:它定义在frameworks/native/include/binder/IInterface.h中。实际上,BpInterface是一个模板类,同时继承了BpRefBase和INTERFACE,这里的INTERFACE是模板。像IServiceManager,IMediaPlayerService等Server都是通过继承模板类是实现的,相关的代码如下:

template<typename INTERFACE>class BpInterface : public INTERFACE, public BpRefBase{public:                                BpInterface(const sp<IBinder>& remote);protected:    virtual IBinder*            onAsBinder();};

(2).BnInterface:它定义在frameworks/native/include/binder/IInterface.h中。和BpInterface类似,BnInterface也是一个模板类,它同时继承了BBinder和INTERFACE。像BnServiceManager,BnMediaPlayerService等本地Server都是通过继承模板类是实现的,相关的代码如下:

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();};

   前面篇幅的章节一和章节二让我们对Java层和C++层的Binder有关的类有了一个比较清晰的认识,但是还是比较模糊是不,那么可以通过下面的示意图来一个清晰的整体概括,通过该示意图我们应该能大致上了解Java和C++层的Binder怎么关联起来了。


3.ProcessState

   它的源码定义在它定义在frameworks/native/libs/binder/ProcessState.cpp中。对于开发Android app的读者来说,在Android上层架构中,谷歌妈咪已经很大幅度地弱化了进程的概念了。应用开发的小伙伴能看到的主要是四大组件的概念了,再也找不到以前熟悉的main()函数了。然而,底层程序(C++层次)毕竟还是得跑在一个个进程之上,现在我们就来看底层进程是如何运用Binder机制来完成跨进程通信的。
   在每个进程中,会有一个全局的ProcessState对象。这个很容易理解,ProcessState的字面意思不就是“进程状态”吗,ProcessState的实例是采用单例模式实现的,我们截选其中的一部分重要的:

class ProcessState : public virtual RefBase{public:    static  sp<ProcessState>    self();    ...    void                startThreadPool();    ...    void                spawnPooledThread(bool isMain);    status_t            setThreadPoolMaxThreadCount(size_t maxThreads);private:    friend class IPCThreadState;    ...        struct handle_entry     {        IBinder* binder;        RefBase::weakref_type* refs;    };    handle_entry*       lookupHandleLocked(int32_t handle);    int                 mDriverFD;    void*               mVMStart;    mutable Mutex       mLock;  // protects everything below.        Vector<handle_entry> mHandleToObject;    ...    KeyedVector<String16, sp<IBinder> > mContexts;    ...};

它拥有两个非常重要的成员:mDriverFD和mHandleToObject,我们知道,Binder内核被设计成一个驱动程序,所以ProcessState里专门搞了个mDriverFD域,来记录binder驱动对应的句柄值,以便随时和binder驱动通信。ProcessState对象采用了典型的单例模式,在一个应用进程中,只会有唯一的一个ProcessState对象,它将被进程中的多个线程共用,因此每个进程里的线程其实是共用所打开的那个驱动句柄(mDriverFD)的,示意图如下:

每个进程基本上都是这样的结构,组合起来的示意图就是:

而mHandleToObject是一个Vector矢量数组,它的定义如下:

Vector<handle_entry> mHandleToObject;

矢量数组中的每个元素都保存了两个变量:Server的句柄,以及Server对应的BpBinder对象。实际上,Server的句柄是"Server在Binder驱动中的Binder引用的描述";句柄0是ServiceManager的句柄。其中的binder域,记录的就是BpBinder对象。


4.IPCThreadState

   它定义在frameworks/native/libs/binder/IPCThreadState.cpp中中。IPCThreadState的实例也是采用单例模式实现的,它是正在与Binder驱动进行交互的类,和Binder内核层的binder_thread相对应

class IPCThreadState{public:    static  IPCThreadState*     self();...            sp<ProcessState>    process();            ...            void                joinThreadPool(bool isMain = true);                        // Stop the local process.            void                stopProcess(bool immediate = true);                        status_t            transact(int32_t handle,                                         uint32_t code, const Parcel& data,                                         Parcel* reply, uint32_t flags);...private:                                IPCThreadState();                                ~IPCThreadState();            status_t            sendReply(const Parcel& reply, uint32_t flags);            status_t            waitForResponse(Parcel *reply,                                                status_t *acquireResult=NULL);            status_t            talkWithDriver(bool doReceive=true);            status_t            writeTransactionData(int32_t cmd,                                                     uint32_t binderFlags,                                                     int32_t handle,                                                     uint32_t code,                                                     const Parcel& data,                                                     status_t* statusBuffer);            status_t            getAndExecuteCommand();            status_t            executeCommand(int32_t command);            void                processPendingDerefs();            void                clearCaller();    static  void                threadDestructor(void *st);    static  void                freeBuffer(Parcel* parcel,                                           const uint8_t* data, size_t dataSize,                                           const binder_size_t* objects, size_t objectsSize,                                           void* cookie);        const   sp<ProcessState>    mProcess;    const   pid_t               mMyThreadId;...};

总结

   理解上面的基本概念之后,我们现在就从整体上对涉及到的Binder概念对它们进行一下总结和概括!对于一个Server而言,它都会存在一个"远程BpBinder对象"和"本地BBinder对象"。
(01) 远程BpBinder对象的作用:是和Binder驱动进行交互。具体的方式是,当Server要向Binder发起事务请求时,会调用BpBinder的transact()接口,而该接口会调用到IPCThreadState::transact()接口,通过IPCThreadState类来和Binder驱动交互。此外,该BpBinder在Binder驱动中的Binder引用的描述会被保存到ProcessState的mHandleToObject矢量缓冲数组中。
(02) 本地BBinder对象的作用:是Server响应Client请求的类。当Client有请求发送给Server时,都会调用到BBinder的onTransact()函数,而每个Server都会覆盖onTransact()函数。这样,每个Server就可以在onTransact()中根据自己的情况对请求进行处理。

更多相关文章

  1. 类和 Json对象
  2. 打造Android的中文Siri语音助手(一)——小I机器人的接口
  3. 图解 Android(安卓)Handler 线程消息机制
  4. Android(安卓)绑定Service 实现android控制service的生命周期
  5. Android,谁动了我的内存
  6. Android(安卓)HIDL第一个HelloWorld demo
  7. 【如何在不同Android设备中得到有效的AudioRecord实例】
  8. Android(安卓)Activity应用窗口的创建过程分析
  9. 图解 Android(安卓)Handler 线程消息机制

随机推荐

  1. Android(安卓)HTTP
  2. MTK Android(安卓)Driver :sensor
  3. Android(安卓)P 系统应用无法对外置SD卡
  4. android 全面讲解BroadCastReceiver
  5. 选项卡片段
  6. android 设置壁纸几种方法
  7. android菜单参考资料
  8. android操作xml
  9. Android多媒体开发(5)————利用Android(
  10. Android内核的根文件系统