在Android系统中,进程间传递的数据包括Java语言支持的基本数据类型和用户自定义的数据类型,为了使数据能够穿越进程边界,所有数据都必须是“可打包”。对于Java语言的基本数据类型,打包过程是自动完成的。但对于自定义的数据类型,用户需要实现Parcelable接口,使自定义的数据类型能够转换为系统级原语保存在Parcel对象中,穿越进程边界后可再转换为初始格式。
AIDL支持的数据类型如下表:
类型 | 说明 | 需要引入 |
---|---|---|
基本数据类型 | boolean、byte、short、int、 long、char、float、double |
否 |
String | java.lang.String | 否 |
CharSequence | java.lang.CharSequence | 否 |
List | 其中元素都必须是AIDL支持的数据类型 | 否 |
Map | 其中ket和value都必须是AIDL支持的数据类型 | 否 |
其他AIDL接口 | 任何其他使用AIDL语言生成的接口类型 | 是 |
Parcelable对象 | 实现Parcelable接口的对象 | 是 |
下面以ParcelMathServiceDemo示例为参考,说明如何在远程服务中使用自定义类型。这个示例是RemoteMathServiceDemo示例的延续,查看我的RemoteMathServiceDemo示例文章 ,也定义了MathService服务,同样可以为远程调用者提供加法服务,而且同样也是没有启动界面。
不同之处在于MathService服务涉及到了自定义数据类型,在接受到输入参数后,将不再只向调用者返回long类型的数据,而是返回一个包含“加、减、乘、除”全部运算结果的对象。这个对象是一个自定义的类,为了能够使其他AIDL文件可以使用这个自定义的类,需要使用AIDL语言声明这个类。
首先建立AllResult.aidl文件
然后在AllResult.aidl文件中声明AllResult类,AllResult.aidl文件中的代码如下:
// AllResult.aidl
package com.example.remotemathservicedemo;
//在这里声明任何非默认类型
parcelable AllResult;
(这个简陋的aidl文件可不会自动生成对应的java接口文件哦)
然后在IMathService.aidl中为全运算增加新函数,返回类型就是在AllResult.aidl中定义的AllResult,代码如下:
// IMathService.aidl
package com.example.remotemathservicedemo;
// Declare any non-default types here with import statements
interface IMathService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
long Add(long a,long b);
AllResult ComputeAll(long a,long b);
}
然后Build->Make Project 重新生成接口文件,使增加的新函数生效。这时候在新生成的IMathService.java中会提示错误,因为其中需要关于AllResult的信息都找不到。
接下来手动构造AllResult类,可以放在和自动生成的IMathService.java同目录下。下面先把AllResult.java的完整代码贴出来:
package com.example.remotemathservicedemo;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by yinghao on 2016/5/7.
*/
public class