Binder入门

来源:互联网 发布:linux mongodb安装 编辑:程序博客网 时间:2024/05/17 19:15

整体流程

参考


        XXXXNative指的就是AIDL中的Stub。

        服务端需提供一个实体对象给客户端,这个对象就是XXXXService的实例。这个对象应该包括自己想提供给客户端的功能(即IXXXX中声明的方法)。

        客户端最初拿到的只是一个IBinder类型的对象,该对象中并没有任何一个服务端提供出来的功能——即没有IXXXX中定义的方法。因此建立一个代理类(XXXXProxy)实现IXXXX接口,此时客户端就可以使用这个代理类调用IXXXX的方法,而代理类内部使用IBinder对象进行IPC操作,将客户端的请求以及相应的参数发到服务端中。下面是IWindowManager.Stub.Proxy中的方法:

            @Override            public boolean startViewServer(int port) throws android.os.RemoteException {                android.os.Parcel _data = android.os.Parcel.obtain();                android.os.Parcel _reply = android.os.Parcel.obtain();                boolean _result;                try {                    _data.writeInterfaceToken(DESCRIPTOR);                    _data.writeInt(port);                    mRemote.transact(Stub.TRANSACTION_startViewServer, _data, _reply, 0);                    _reply.readException();                    _result = (0 != _reply.readInt());                } finally {                    _reply.recycle();                    _data.recycle();                }                return _result;            }

        mRemote就是客户端最先拿到IBinder对象,Proxy实现了IWindowManager接口,所以可以提供IWindowManager中定义的方法。客户端拿到Proxy对象,调用其中方法,最终还是通过拿到的IBinder对象进行IPC

        这个Proxy有点类似于适配器,将IBinder的对象转换成IXXXX类型的对象。

        IPC时,服务端与客户端的数据交换都需要首先转换成Parcel,并需要解析Parcel拿到自己的数据。Native与Proxy层封装了这份工作。

        服务端返回一个Binder类型的对象(该对象同时实现了IXXXX接口);客户端拿到一个IBinder类型的对象,并为该对象提供一个代理(代理类实现了IXXXX接口),客户端调用代理类中的方法,代理类使用IBinder进行IPC。由IBinder对象与服务端的返回的对象进行匹配。这就是整体的流程。此流程中,IPC的主要操作都是由客户端最先拿到的IBinder对象完成的。

IInterface

        IPC时,server需向client提供一套接口,这个接口定义了server能提供的操作,而这个接口必须继承IInterface。对它的官方说明如下:

 Base class for Binder interfaces.  When defining a new interface,you must derive it from IInterface.

        Binder接口的基类,当定义一个新的接口时,必须从该类派生。这里的Binder接口指的就是Server向外界提供的接口——用于定义自己所能提供的所有的操作,记该接口为CustomItf。

IBinder与Binder

        server-client通信时,服务端需要返回一个对象给客户端——客户端就是利用该对象与服务端进行交互的。

        对于服务端返回的对象,它首先应该实现了CustomItf接口,只有这样客户端才能使用到服务端在接口中定义的方法。同时它必须要继承于Binder(应该是实现IBinder接口的,但Binder实现了IBinder接口,而且官方建议继承Binder对象,不建议直接实现IBinder接口)。

Stub

        通常还可以看到Stub类,它继承于Binder,同时也实现了CustomItf。为什么需要这一层?因为client端往server端发数据时,需要先将数据转成Parcel,server端接收到后需要先将数据还原,然后传入到相应的方法中,再将方法的处理结果转成Parcel,最后通过Binder返回到client中。

        在这个过程,需要将Parcel还原成数据,并将处理后的数据转换成Parcel,而Stub就是处理该过程的。这使用serObj只需要专注于CustomItf定义的方法。

Proxy

        以AIDL为例,在Stub类内部一般有一个Proxy类,该类就是clientObj的类型。在IPC时,server与client要想向对方发送数据,所发送的数据都必须先转换成Parcel,而Proxy类封装了client端数据与Parcel转换的过程

问题

        1,客户端最初拿到的IBinder对象是怎么来的(它是BinderProxy类型的对象)。

        2,上述的IBinder对象是怎么与服务端返回的serverObj对应上的。

0 0
原创粉丝点击