使用AIDL实现进程间的通信之复杂类型传递

764 查看

上次讲到简单的AIDL进程间通信的操作,客户端向服务端发送一个String类型的参数,服务端也返回一个String类型的结果,看似已经可以完成基本的需要了。不过在有的时候,简单的数据类型并不能满足我们的需求,我们就需要考虑怎样向服务端传递复杂的数据类型。今天就来讲一下如何向服务端传递复杂类型的问题。

首先要了解一下AIDL对Java类型的支持。

1.AIDL支持Java原始数据类型。

2.AIDL支持String和CharSequence。

3.AIDL支持传递其他AIDL接口,但你引用的每个AIDL接口都需要一个import语句,即使位于同一个包中。

4.AIDL支持传递实现了android.os.Parcelable接口的复杂类型,同样在引用这些类型时也需要import语句。(Parcelable接口告诉Android运行时在封送(marshalling)和解封送(unmarshalling)过程中实现如何序列化和反序列化对象,你可以很容易联想到java.io.Serializable接口。有些朋友可能会有疑问,两种接口功能确实类似,但为什么Android不用内置的Java序列化机制,而偏偏要搞一套新东西呢?这是因为Android团队认为Java中的序列化太慢,难以满足Android的进程间通信需求,所以他们构建了Parcelable解决方案。Parcelable要求显示序列化类的成员,但最终序列化对象的速度将快很多。另外要注意的是,Android提供了两种机制来将数据传递给另一个进程,第一种是使用Intent将数据束(Bundle)传递给活动,第二种也就是Parcelable传递给服务。这两种机制不可互换,不要混淆。也就是说,Parcelable无法传递给活动,只能用作AIDL定义的一部分)。

5.AIDL支持java.util.List和java.util.Map,但是有一些限制。集合中项的允许数据类型包括Java原始类型、String、CharSequence或是android.os.Parcelable。无需为List和Map提供import语句,但需要为Parcelable提供import语句。

6.非原始类型中,除了String和CharSequence以外,其余均需要一个方向指示符。方向指示符包括in、out、和inout。in表示由客户端设置,out表示由服务端设置,inout表示客户端和服务端都设置了该值。

接下来就演示一下具体的流程:

我们先看一下服务端的结构:

其中,Person类是我们要在服务端和客户端中间进行传递的类型,代码如下:

然后我们需要在同一包下建立一个与包含复杂类型的Person.java文件匹配的Person.aidl文件,代码如下: