参考文章: 《Android 艺术探索》
注意这里说的是 Binder 本身,即手动实现 Binder,而不是基于 AIDL(Android 接口定义语言)。
在 AIDL 文件中,只支持以下几种类型:
1、基本数据类型
2、 String 和 CharSequence
3、只支持 ArrayList,且里面的元素也要被 AIDL 支持
4、只支持 HashMap,且里面的元素也要被 AIDL 支持,包括 key 和 value
5、实现了 Parcelable 的对象
6、AIDL:所有 AIDL 接口本身也可以在 AIDL 文件中使用(无法使用普通接口)
而无法直接支持 Serializable 类型的数据,这是因为使用 AIDL 的时候,我们只需要定义相应的 AIDL 文件。
然后会由系统生成对应的与 Binder 相关的内容,而由系统生成对应内容的时候,对于序列化对象是基于 Parcelable 接口来处理的,因此此时并不直接支持 Serializable 类型的数据。
但是有个折中的方法,因为 AIDL 支持 Parcelable 类型的对象,因此可以在 Parcelable 类型的对象里面添加 Serializable 类型的成员变量。 因为 Parcel 提供了对于 Serializable 类型数据的支持。
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeSerializable(data);
}
实现了 Parcelable 接口的对象,要重写 writeToParcel()
方法。
但是,对于 Binder 机制本身,是可以支持 Serializable 类型的对象的传输的。
从理论上来说,Serializable 也是序列化的一种方式,跨进程传输时对于该序列化方法应该是要支持的。
另外,从实际情景中来推测,也是成立的,如 AIDL 中,对于 Parcelable 对象里面的 Serilizable 类型的成员变量是支持的。而 AIDL 的底层实现就是 Binder。
下面,也将用实际的代码去验证。即手动的去实现 Binder。
1、定义 Binder 接口与实体类
public interface IBookManager2 extends IInterface {
static final String DESCRIPTOR = "test.zzq.myapplication.aidl.IBookManager2";
static final int TRANSACTION_getBookList = IBinder.FIRST_CALL_TRANSACTION + 0;
static final int TRANSACTION_addBokk = IBinder.FIRST_CALL_TRANSACTION + 1;
public List<Book2> getBookList() throws RemoteException;
public void addBook(Book2 book) throws RemoteException;
}
其中实体类是实现了 Serializable 接口的,而非 Parcelable。
public class Book2 implements Serializable {
public int bookId;
public String bookName;
public Book2() {
}
public Book2(int id, String name) {
bookId = id;
bookName = name;
}
public static Book2 createFromParcel(Parcel parcel) {
Book2 book2 = new Book2();
book2.bookId = parcel.readInt();
book2.bookName = parcel.readString();
return book2;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(bookId);
dest.writeString(bookName);
}
@Override
public String toString() {
return String.format("[bookId:%s, bookName:%s]", bookId, bookName);
}
}
2、手动实现 Binder 对象类
public class BookManagerImpl extends Binder implements IBookManager2 {
private CopyOnWriteArrayList<Book2> mBookList;
public BookManagerImpl(CopyOnWriteArrayList<Book2> list) {
this.attachInterface(this, DESCRIPTOR);
mBookList = list;
}
public static IBookManager2 asInterface(IBinder obj) {
if (obj == null)