在AIDL接口中除了可以使用java自带的数据类型外,还可以使用自定义的数据类型。如果需要使用自定义数据类型或List,Map中需要封装自定义数据类型需要以下几个步骤:
1.自定义的数据类型实现Pracelable接口。
2.编写自定义数据类型的.aidl文件
3.无论自定义数据类型与aidl接口源文件是否在一个包中,在接口源文件中使用自定义数据类型时都需要显示的import语句导入。
4.将自定义数据类型的,java文件和.aidl文件复制到客户端
自定义数据类型的.aidl文件需要满足:
1.存在与自定义数据类型.java文件相同的package语句
2.parcelable 自定义数据类型的类名
Pracelable接口
任何复合数据类型都是基本类型封装后的集合,因此各种复合数据类型都可以被拆分为基本数据类型再进行传输。比如我们定义一个Student类,有id,name等在传输时是以int,String的集合这样的形式。Pracelable接口约定了数据被序列化传输的方式(Android的研发团队认为JAVA体系中的jjava.io.Serializable在序列化类的成员时效率偏低,不适合性能比较低的移动设备。因此研发了Pracelable并要求显式的序列化类的成员以提高效率)
在Pracelable中定义了以下抽象方法:
public int describeContents():内容接口的描述,通常直接返回0即可
public void writeToParcel(Parcel dest, int flags):用于将当前类的成员写入到Parcel容器中,重写该方法时调用Parcel类的write系列方法即可。如writeInt(),writeString()等。
通常我们需要自定义readFromParcel(Parcel parcel)方法,用于从Parcel容器中读出数据,读出的顺序必须与写入时的顺序一致。
我们还必须创建静态常量CREATOR,实现Parcelable.Creator<T>接口。常量名必须为CREATOR,且必须用public static final修饰。然后重写接口中的抽象方法。其中createFromParcel(Parcel source):这个方法用于从Parcel 容器返回泛型指定的类对象。需要我们自定义构造方法。
接下来用一个例子来说明。在服务端返回List的Student集合在客户端调用
服务端代码:
Student.java
package com.wanghongxiang.customdatatypeservice;
Student.aidlpublic class Student implements Parcelable { private String name; private String from; private int age; public static final Parcelable.Creator<Student> CREATOR=new Parcelable.Creator<Student>(){ @Override public Student createFromParcel(Parcel source) { return new Student(source); } @Override public Student[] newArray(int size) { return new Student[size]; }}; //自定义构造方法 public Student(Parcel source) { readFromParcel(source); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeString(from); dest.writeInt(age); } //从Parcel容器中读出数据 private void readFromParcel(Parcel from){ this.name=from.readString(); this.from =from.readString(); this.age=from.readInt(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Student(String name, String from, int age) { super(); this.name = name; this.from = from; this.age = age; } @Override public String toString() { return "Student [name=" + name + ", from=" + from + ", age=" + age + "]"; } }
package com.wanghongxiang.customdatatypeservice;
parcelable Student;
StudentService.java
public class StudentService extends Service {
@Override
public IBinder onBind(Intent intent) {
return new InnerBinder();
}
private class InnerBinder extends IStudentAIDL.Stub{
@Override
public List<Student> getStudentList() throws RemoteException {
List<Student> list=new ArrayList<Student>();
list.add(new Student("rose","beijing",18));
list.add(new Student("jack","nanjing",18));
list.add(new Student("laowang","xian",18));
return list;
}
}
}
AndroidManifest.xml中添加如下代码:
<service android:name=".StudentService">
<intent-filter>
<action android:name="android.intent.action.STUDENT" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
客户端代码:
MainActivity.java
public class MainActivity extends Activity {
private ServiceConnection conn;
private IStudentAIDL studentService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
conn=new InnerServiceConnection();
Intent intent=new Intent("android.intent.action.STUDENT");
bindService(intent, conn,BIND_AUTO_CREATE);
}
private class InnerServiceConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
studentService=IStudentAIDL.Stub.asInterface(service);
try {
List<Student> list=studentService.getStudentList();
for(Student s:list){
Log.d("",s.toString());
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}