据我所知,AIDL 编译器不喜欢 Result<Animal> getResult(); 这样的东西。但是,Result getResult(); 确实有效。所以这就是我所做的:
- 使用签名
public class Result<T extends Parcelable> implements Parcelable 创建了一个类。
- 创建了一个新类以放入第一个类中,该类称为 Animal。签名是
public class Animal implements Parcelable。
- 必须在 Result 和 Animal 中实现接口
Parcelable 和 CREATOR 所需的方法,并根据需要为每个类创建一个 AIDL,并在主 AIDL 中导入这两个类。这些东西是常规的 AIDL 工作,在 AIDL site 中有描述。
- 在
Result 中,我们不仅存储T 类型的对象,还存储Class 对象。在编写包裹时,我们需要先编写类类型,然后再编写通用对象。阅读时,我们按照相同的顺序进行。我们需要编写类类型,因为当我们阅读时,我们必须做t = (T) in.readValue(classType.getClassLoader());,而没有类类型我们do not know 要获取哪个类加载器。可能还有其他方法可以做到这一点,但这就是我在这个例子中的做法。
- 在客户端节点接收时,我可以成功执行
Result<Animal> r = MainActivity.this.service.getResult();,然后在Result和Animal上调用方法。
可以在下面找到一些有望使事情更清晰的代码。
public class Result<T extends Parcelable> implements Parcelable {
private String msg;
private Class classType;
private T value;
public Result(String msg, T value, Class classType) {
this.msg = msg;
this.value = value;
this.classType = classType;
}
// to reconstruct object
public Result(Parcel in) {
readFromParcel(in);
}
public String getMsg() {
return msg;
}
public T getValue() {
return value;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(msg);
dest.writeValue(classType);
dest.writeValue(value);
}
private void readFromParcel(Parcel in) {
this.msg = in.readString();
this.classType = (Class) in.readValue(Class.class.getClassLoader());
this.value = (T) in.readValue(classType.getClassLoader());
}
public static final Creator<Result> CREATOR = new Creator<Result>() {
@Override
public Result createFromParcel(Parcel source) {
return new Result(source);
}
@Override
public Result[] newArray(int size) {
return new Result[size];
}
};
}
public class Animal implements Parcelable {
private int n;
public Animal(int n) {
this.n = n;
}
public Animal(Parcel in) {
readFromParcel(in);
}
public int getN() {
return n;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(n);
}
private void readFromParcel(Parcel in) {
n = in.readInt();
}
public static final Creator<Animal> CREATOR = new Creator<Animal>() {
@Override
public Animal createFromParcel(Parcel source) {
return new Animal(source);
}
@Override
public Animal[] newArray(int size) {
return new Animal[size];
}
};
}
服务摘录:
@Override
public Result getResult() throws RemoteException {
Result<Animal> r = new Result<Animal>("this is an animal", new Animal(42), Animal.class);
return r;
}
客户摘录:
Result<Animal> r = MainActivity.this.service.getResult();
Log.d(TAG, "Received the following (Outer): " + r.getMsg());
Log.d(TAG, "Received the following (Inner): " + r.getValue().getN());
另一种方法是将Result的签名更改为public class Result<T extends Serializable> implements Parcelable,使Animal实现Serializable,然后在Result中使用dest.writeSerializable(value);和this.value = (T) in.readSerializable();。
使用这种方法,不需要将类类型发送到另一端,甚至根本不需要使用它。尽管如此,你还是会支付price。