欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Binder机制(三) Binder相关的接口和类

程序员文章站 2024-03-23 23:29:22
...

     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相关的接口或类的继承关系如下:
Android Binder机制(三) 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 ,下面我们来分别进行简单的介绍,在正式介绍前先奉上一关于上述几个接口和类之前的关系图,这就好比相亲之前得让介绍人先给个对方的照片,看过以后才能确定是否有进一步发展的空间不是!

Android Binder机制(三) Binder相关的接口和类

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