gpt4 book ai didi

java - 带有 Java 泛型的 Android AIDL

转载 作者:太空宇宙 更新时间:2023-11-03 13:20:47 62 4
gpt4 key购买 nike

Android AIDL 是否支持泛型?

例如,假设我有一个类 Result<T> ,其中 T 可以是任何类型,包括基元(通过自动装箱)或其他自定义类,例如 Car .任何自定义类实现 Parcelable根据 Binder 的要求。

然后可能的 AIDL 方法签名将是

  • Result<Car> m1();
  • Result<Void> m2();
  • Result<Boolean> m3();

最佳答案

据我所知,AIDL 编译器不喜欢 Result<Animal> getResult(); 之类的东西.然而,Result getResult();确实有效。所以这就是我所做的:

  1. 创建了一个带有签名的类 public class Result<T extends Parcelable> implements Parcelable .
  2. 创建了一个新类以放入第一个类,名为 Animal。签名是public class Animal implements Parcelable .
  3. 必须实现接口(interface)所需的方法 Parcelable和一个 CREATOR在 Result 和 Animal 中,还根据需要为每个创建了一个 AIDL,并在主 AIDL 中导入了这两个类。这些东西是常规的 AIDL 工作,在 AIDL site 中有描述。 .
  4. 内部Result ,我们不仅存储类型为 T 的对象还有一个Class目的。在编写 parcel 时,我们需要先编写类类型,然后才编写通用对象。阅读时,我们按照相同的顺序进行。我们需要写类类型,因为当我们阅读时我们必须做 t = (T) in.readValue(classType.getClassLoader());没有类类型我们 do not know要获取哪个类加载器。可能还有其他方法可以做到这一点,但我在这个例子中就是这样做的。
  5. 在客户端节点上接收时,我可以成功执行 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 , 然后使用 dest.writeSerializable(value);this.value = (T) in.readSerializable();里面的结果。

使用这种方法,不需要将类类型发送到另一端,甚至根本不需要使用它。尽管如此,您还是要支付 price .

关于java - 带有 Java 泛型的 Android AIDL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28052195/

62 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com