昨天开始认真研究了一下AIDL,使用AIDL绑定远程服务并且传递复杂自定义的参数,在使用过程中碰到了一些问题,网上的技术贴有很多不全面的,另外有些细节部分根本不会提到,然后就查找了很多技术贴,自己动手完整地实现了功能并且把出现的问题解决,这篇文章记录下来细节和要点,供自己忘记时温习。我们使用的自定义类为Pet和Person。
下面只指出细节和关键点:
1.服务端AIDL下的包和java下的包一一对应,如果你想把新建的Person类,Pet类放在一个包javabean中,那么在AIDL对应的包下也需要建一个javabean的包再建Person.aidl和Dog.aidl
2.Person类和Dog类的序列化,也就是实现Parcelable接口这里是大写,这里特别注意最后一个
readFromParcel方法,你用AndroidStudio自动的模板是没有这个方法的,所以是自己添加上去的。这里是一个坑,我们在IMyAidlInterface.aidl文件里面的代码如下: package com.mike.servicepro; import com.mike.servicepro.javabean.Person; import com.mike.servicepro.javabean.Dog; interface IMyAidlInterface { String intInfo(in Person person);//in表明是由客户端到服务端 String outInfo(out Person person);//out表明是有服务端到客户端 String inoutInfo(inout Person person);//inout表明可以双向通信 List<Dog> getDogInfo(); } 因为默认是in这种方式,所以如果要用到后面的两种就需要使用 readFromParcel方法读取数据,如果不需要用到(out和inout就不需要写),而在模板中它是用 protected Person(Parcel in) { name = in.readString(); age = in.readInt(); }这个方法读取数据,所以我们需要手写这个方法。代码如下: public void readFromParcel(Parcel dest) { name = dest.readString(); age = dest.readInt(); } public class Person implements Parcelable{ public String name; public int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } protected Person(Parcel in) { name = in.readString(); age = in.readInt(); } public static final Creator<Person> CREATOR = new Creator<Person>() { @Override public Person createFromParcel(Parcel in) { return new Person(in); } @Override public Person[] newArray(int size) { return new Person[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); } public void readFromParcel(Parcel dest) { name = dest.readString(); age = dest.readInt(); } }3.服务端需要在AIDL下面创建一个自定义实体类的AIDL文件,Person.aidl
package com.mike.servicepro.javabean; parcelable Person; 4.Dog.adil是一样的 package com.mike.servicepro.javabean;parcelable Dog; 就两行代码,注意 parcelable是小写的。5.客户端部分AIDL包下是将服务端AIDL下的文件全部复制,然后再在java包下新建一个和服务端的包名相同的包com.mike.servicepro,然后如果有javabean包,也相应地需要新建,然后将服务端的实体类Person,Pet复制过来。
6.在5.0以后需要显式地绑定服务,一种是setAction和setPackage,第二种是setClass,这里intent里面的包名是和AIDL服务端的包名相同com.mike.servicepro。
7.复杂的数据都可以传递,比如List,map等等,如果泛型是自定义类那就需要序列化。。。