我有一个基本的抽象类,看起来像这样。
public abstract class Species implements Parcelable {
public Species() {
}
public abstract String name();
}
然后我的人类类看起来像这样。
@AutoValue
public abstract class Human extends Species implements Parcelable {
public static Human create(String humanVariable) {
return new AutoValue_Human(humanVariable);
}
public static Human create(String name, String humanVariable) {
return new AutoValue_Human(name, humanVariable);
}
public static TypeAdapter<Human> typeAdapter(Gson gson) {
return new AutoValue_Human.GsonTypeAdapter(gson);
}
@SerializedName("name")
public abstract String name();
@Nullable
@SerializedName("human_variable")
public abstract String humanVariable();
}
E/com.service.androidbrain.util.networking.RetrofitCallback.onFailure: 无法调用 public com.service.example.models.Species(( 而没有 参数
但是由于某种原因,我收到此错误,我不明白发生了什么,知道吗?
auto-value-gson
不支持您要实现的行为。
我假设您声明了您的改造服务以返回Call<Species>
,而只有Human.typeAdapter(Gson)
注册到 Gson。这在 Gson 不知道如何直接创建Species
实例中得出结论。
为此,您必须为Species
(创建并(安装另一种类型的适配器,该适配器知道如何识别物种的实际子类型,并将所有模型创建委托给特定类型的适配器。
我敢肯定你只是没有正确实例化GsonConverterFactory
。从我对你上一个问题的回答来看:
@GsonTypeAdapterFactory
abstract class HumanAdapterFactory
implements TypeAdapterFactory {
public static TypeAdapterFactory create() {
return new AutoValueGson_HumanAdapterFactory();
}
}
因此,不需要执行以下操作:
public static TypeAdapter<Human> typeAdapter(Gson gson) {
return new AutoValue_Human.GsonTypeAdapter(gson);
}
所以你只需要实例化Gson
:
new GsonBuilder()
...
.registerTypeAdapterFactory(HumanAdapterFactory.create())
.create();
并像这样配置改造实例:
new Retrofit.Builder()
...
.addConverterFactory(GsonConverterFactory.create(gson)) // THIS is necessary
.build();
并确保您的服务接口在 Human
上运行,而不是Species
:
interface IService {
@GET("/") // This is probably what you really want
Call<Human> getHuman();
@GET("/") // How can you know WHAT the Species is here?
Call<Species> getSpecies();
}
如果你真的想使用getSpecies()
,你必须知道特定对象的Species
接口的真实类型是什么:所以你必须使用InstanceCreator
或检测某些信息的真实类型。这两种方法在我的回答中都有描述。为了使它工作:
final Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(HumanAdapterFactory.create())
.registerTypeAdapterFactory(new TypeAdapterFactory() {
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
// ... that big type adapter here from that answer OR InstanceCreator by it's not useful here
}
})
.create();
final Retrofit retrofit = new Retrofit.Builder()
...
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
final IService service = retrofit.create(IService.class);
final Species species = service.getSpecies()
.execute()
.body();
System.out.println(species.getClass());
System.out.println(species.name());
这就是您所需要的,但Call<Human> getHuman();
是这里的最佳选择。
您应该更喜欢组合而不是继承,因为至少目前在 AutoValue
中无法执行此操作。
在 github 上看到这个问题。
我通过从我的类中删除来解决这个问题抽象一词
Ej以前
public abstract class Post {
private int userId;
private int id;
private String title;
}
后
public class Post {
private int userId;
private int id;
private String title;
}