美文网首页
Binder AIDL相关内容解释

Binder AIDL相关内容解释

作者: 戴维王 | 来源:发表于2020-04-30 18:24 被阅读0次
  • Binder是Android提供的一种高效安全的IPC(Inter-Process Communication进程间通信)机制;
  • AIDL Android Interface Definition Language(安卓接口定义语言),它是一种以.aidl为后缀名的接口文件,在文件中定义远程服务对外提供的接口方法,这个文件是不会被编译到apk中的,它的目的是让IDE也就是Android Studio依照定义的内容生成对应的.java文件,生成的.java文件才是完成Binder提供给Client和Service间通信的实现类,也就是说,我们可以不使用AIDL文件手写一个类用于实现Client到Service的远程调用,事实上当我们为了在通信中加入特殊的处理时(比如校验调用方权限和参数封装)就不得不手写这个类,包括很多Android的原生服务的类也都是手写的,最常见的就是用于启动Activity的类ActivityManagerNative就是这样的一个类;

IDE根据AIDL文件生成的.java文件

注:大篇幅的粘贴代码会影响读者对文章内容的阅读,所以我希望大家可以对照着.java文件看这篇文章。
文件内容是一个继承自android.os.IInterface的与AIDL文件同名的接口(以下简称AIDL接口),它包含了AIDL中定义所有方法,其核心是一个名为Stub的静态内部类,以及类Stub的静态内部类Proxy。

Stub

Stub是一个继承自类android.os.Binder的抽象类也就是说Stub是一个Binder类(这也就意味着由实现了Stub的类派生出的对象是可以跨进程传递的,IPC中,Service的onBinder方法返回的就是由Stub的实现类派生的对象),它同时还实现了AIDL接口,Stub最终会由Service端实现,用于对外提供服务。它包含了以下几个部分:

  • DESCRIPTOR Binder的唯一标识,一般用AIDL接口的全名表示,它是Binder的唯一标识;
  • asInterface(android.os.IBinder obj) 为Client提供Service的Binder实例,方法的入参在Client与Service同进程时是Service的Binder实例,跨进程时是Service Binder的代理类BinderProxy实例(这个实例是真正处理远程调用的实例,后面说的根据它派生的Stub.Proxy实例是为了处理传参和返回值的),当Client与Service处在同一个进程时方法直接返回Service端的Binder实例,跨进程时则返回使用obj派生的Stub.Proxy实例;
  • asBinder 返回当前Binder对象;
  • onTransact 方法运行在Service端的Binder线程池中,当Client发起远程调用时,系统底层会将调用封装后交由onTransact处理,该方法的原型是public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)。Service通过code区分Client要调用的目标方法是哪个(code在Stub内定义),接着从data中取出目标方法所需的参数(如果有),然后执行目标方法,当目标方法执行完毕后,就向reply写入返回值(如果有),如果onTransact方法返回flase,表示Client远程调用失败,我们可以利用这个特性来做Client权限判断;
  • Proxy 为Client提供Service的代理,Proxy是运行在Client进程的,当Client与Service处于同一进程时是不会使用的Proxy的,因为在Client在调用Stub.asInterface方法获取Service端Binder实例时会直接返回Binder的原始实例而不是Proxy代理实例。

Proxy

该类是Service端在Client端的代理类,实现了AIDL接口,类中的方法也是代理方法,负责参数处理-->远程调用目标方法-->返回值处理,代理方法中会调用一个远程调用相关的重要方法transact,方法的原型是public boolean transact(int code, Parcel data, Parcel reply, int flags),方法的参数:

  • code 用于区分目标方法,code值在Stub中有常量定义;
  • data 入参,如果目标方法是需要传参的切Client调用代理方法时传入了参数则为data添加参数,如果是基本类型或String则直接添加,如果是实现了Parcelable的对象则将对象序列化写入data;
  • reply 返回值,如果目标方法有返回值则会将返回值写入reply中,这样当transact方法结束后代理方法就可以从reply中取得返回值;
  • flags 通常是0,也可以传入IBinder.FLAG_ONEWAY,表示不关心远程方法的执行情况,也就是说发起远程调用时不会阻塞发起调用的线程。
    对data和reply的介绍也就是介绍代理方法是如何处理远程调用传参和返回值的。

相关文章

网友评论

      本文标题:Binder AIDL相关内容解释

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