Android 使用AIDL在进程间通信

这是一种比startService更复杂的启动方式,同时使用这种方式启动的service也能完成更多的事情,比如其他组件可向其发送请求,接受来自它的响应,甚至通过它来进行IPC(Inter-Process Communication)等等。我们通常将绑定它的组件称为客户端,而称它为服务端。如果要创建一个支持绑定的service,我们必须要重写它的onBind()方法。这个方法会返回一个IBinder对象,它是客户端用来和服务器进行交互的接口,是为高性能而设计的轻量级远程调用机制的核心部分。而要得到IBinder接口,我们通常有三种方式:继承Binder类,使用Messenger类,使用AIDL。

AIDL,即Android Interface Definition Language,Android接口定义语言。它是一种IDL语言,可以拿来生成用于IPC的代码。其实就是一个模板,在使用中,实际上起作用的并不是我们写的AIDL代码,而是系统根据它生成的一个IInterface实例的代码。一样的流程,一样的结构,只是根据具体的AIDL文件的不同有细微的变动。所以其实AIDL就是为了避免我们一遍遍的写一些千篇一律的代码而出现的一个模板。

它和 Java 不一样的地方:

文件类型:用AIDL书写的文件的后缀是 .aidl,而不是 .java。
数据类型:AIDL默认支持一些数据类型,在使用这些数据类型的时候是不需要导包的,
但是除了这些类型之外的数据类型,在使用之前必须导包,就算目标文件与当前正在编写的 .aidl 文件
在同一个包下——在 Java 中,这种情况是不需要导包的。比如,现在我们编写了两个文件
,一个叫做 Book.java ,另一个叫做 BookManager.aidl,它们都在 com.lypeer.aidldemo 包下 ,
现在我们需要在 .aidl 文件里使用 Book 对象,那么我们就必须在 .aidl 文件里面写上
 import com.lypeer.aidldemo.Book; 哪怕 .java 文件和 .aidl 文件就在一个包下。
默认支持的数据类型包括:
Java中的八种基本数据类型,包括 byte,short,int,long,float,double,boolean,char。
String 类型。
CharSequence类型。
List类型:List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable。List可以使用泛型。
Map类型:Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable。Map是不支持泛型的。

定向tag:AIDL中的定向 tag 表示了在跨进程通信中数据的流向,其中 in 表示数据只能由客户端流向服务端, out 表示数据只能由服务端流向客户端,而 inout 则表示数据可在服务端与客户端之间双向流通。其中,数据流向是针对在客户端中的那个传入方法的对象而言的。

in 为定向 tag 的话表现为服务端将会接收到一个那个对象的完整数据,但是客户端的那个对象不会因为服务端对传参的修改而发生变动;

out 的话表现为服务端将会接收到那个对象的的空对象,但是在服务端对接收到的空对象有任何修改之后客户端将会同步变动;

inout 为定向 tag 的情况下,服务端将会接收到客户端传来对象的完整信息,并且客户端将会同步服务端对该对象的任何变动。

另外,Java 中的基本类型和 String ,CharSequence 的定向 tag 默认且只能是 in 。请不要滥用定向 tag ,而是要根据需要选取合适的——要是不管三七二十一,全都一上来就用 inout ,等工程大了系统的开销就会大很多——因为排列整理参数的开销是很昂贵的。

两种AIDL文件:在我的理解里,所有的AIDL文件大致可以分为两类。一类是用来定义parcelable对象,以供其他AIDL文件使用AIDL中非默认支持的数据类型的。一类是用来定义方法接口,以供系统使用来完成跨进程通信的。可以看到,两类文件都是在“定义”些什么,而不涉及具体的实现,这就是为什么它叫做“Android接口定义语言”。
注:所有的非默认支持数据类型必须通过第一类AIDL文件定义才能被使用。

(未完成)
 

你可能感兴趣的:(Android,android)