美文网首页
Binder AIDL proxy stub

Binder AIDL proxy stub

作者: WaterYuan | 来源:发表于2019-05-13 14:59 被阅读0次

    Binder与AIDL?
    Android中有多种IPC机制,如AIDL,Messenger,Socket,ContentProvider,但是这些机制底层大都用了Binder机制来实现的,什么是Binder?要了解Android系统中的IPC我们首先要了解的就是Binder;

    1、Binder机制原理

    Binder机制原理:
    1.客户端获取服务端的代理对象(proxy)
    在客户端建立一个服务端进程的代理对象
    2.客户端通过调用代理对象向服务端发送请求。
    3.代理对象将用户请求通过Binder驱动发送到服务器进程;
    4.服务端进程处理客户端发过来的请求,处理完之后通过Binder驱动返回处理结果给客户端的服务端代理对象;
    5.代理对象将请求结果进一步返回给客户端进程。

    2、Binder机制的组成

    1.Client、Server、ServiceManager均在用户空间中实现,而Binder驱动程序则是在内核空间中实现的;
    2.Server进程先注册一些Service到ServiceManager中,ServiceManager负责管理这些Service并向Client提供相关的接口;
    3.必须先从ServiceManager中获取该Service的相关信息,Client根据得到的Service信息与Service所在的Server进程建立通信,之后Clent就可以与Service进行交互了;
    4.Binder驱动程序提供设备文件/dev/binder与用户空间进行交互,Client、Server和ServiceManager通过open和ioctl文件操作函数与Binder驱动程序进行通信;
    5.Client、Server、ServiceManager三者之间的交互都是基于Binder通信的,所以通过任意两者这件的关系,都可以解释Binder的机制。

    3、AIDL的实现

    1. 首先是服务端:我们首先创建一个AIDL文件,其实就是定义我们的方法接口
      https://github.com/WaterYuanData/AIDL/blob/master/aidlservice/src/main/aidl/com/example/aidlservice/IDataInterface.aidl
      接下来我们创建一个Service,我们在Service中实现了我们定义的AIDL接口,并且服务端在绑定接口的时候将服务端的IBinder对象返回给客户端;
      https://github.com/WaterYuanData/AIDL/blob/master/aidlservice/src/main/java/com/example/aidlservice/RoomService.java
      配置
      https://github.com/WaterYuanData/AIDL/blob/master/aidlservice/src/main/AndroidManifest.xml
      客户端拿到服务端的IBinder对象就可以调用服务端的方法了;
    2. 客户端实现如下:
      和服务端定义一个一模一样的aidl文件(包名、方法名,参数必须一致)
      绑定服务端的服务
      客户端拿到服务端的IBinder对象就可以调用服务端的方法了;
      https://github.com/WaterYuanData/AIDL/blob/master/aidlclient/src/main/java/com/example/aidlclient/MainActivity.java
      其中iDataInterface = IDataInterface.Stub.asInterface(service);
      如果客户端和服务端在同一个进程下,那么asInterface()将返回Stub对象本身,否则返回Stub.Proxy对象。

    参考:https://www.jianshu.com/p/b9b3051a4ff6

    4、理解proxy与stub的工作流程

    我们声明的接口IMyAidlInterface包含了一个静态内部类Stub,并且Stub也继承了IMyAidlInterface,所以Stub是IMyAidlInterface的具体实现,而Stub又是一个抽象类,最终的实现在RemoteService中
    Stub内部包含了一个静态内部类Proxy,同样实现了接口IMyAidlInterface
    可以通过前面的例子梳理一下Stub-proxy的工作流程

    RemoteService中的IBinder对象mServiceBinder是Stub的具体实现,在RemoteService和activity绑定的时候被返回
    被返回的mServiceBinder最终是作为onServiceConnected中的参数,
    Activity端会调用Stub中的静态方法asInterface,mServiceBinder作为参数,最后拿到IMyAidlInterface接口对象myAidlInterface

    在asInterface方法中首先会判断Binder是否处在当前进程,否则构造Proxy并返回,构造Proxy时,把mServiceBinder赋值给mRemote,Proxy中实现的接口getInformation会调用mRemote的transact方法,而Binder的通信是靠transact和onTransact实现的,最后会走到Stub的onTransact,完成对mServiceBinder的调用
    所以,aidl通信体现着代理模式的设计思想,RemoteService具体实现了Stub,Proxy是Stub在本地Activity的代理对象,Proxy与Stub依靠transact和onTransact通信,Proxy与Stub的封装设计最终很方便地完成了Activity与RemoteService跨进程通信

    .aidl编译后才会生成.java文件
    https://www.jianshu.com/p/b5611c9b4d22

    Stub和Stub.Proxy。它们有什么区别呢?

    • 如果在同一个进程下的话,那么asInterface()将返回服务端的Stub对象本身,因为此时根本不需要跨进称通信,那么直接调用Stub对象的接口就可以了,返回的实现就是服务端的Stub实现,也就是根本没有跨进程通信;
    • 如果不是同一个进程,那么asInterface()返回是Stub.Proxy对象,该对象持有着远程的Binder引用,因为现在需要跨进程通信,所以如果调用Stub.Proxy的接口的话,那么它们都将是IPC调用,它会通过调用transact方法去与服务端通信。

    https://blog.csdn.net/scnuxisan225/article/details/49970217

    5、AIDL传输数据限制

    非基本类型需要显式引用,不超过1M

    相关文章

      网友评论

          本文标题:Binder AIDL proxy stub

          本文链接:https://www.haomeiwen.com/subject/mzvkaqtx.html