使用Retrofit进行的继承无法调用,没有args

时间:2017-04-08 13:29:00

标签: android gson retrofit auto-value

我有这个基本的抽象类,看起来像这样。

public abstract class Species implements Parcelable {
    public Species() { 

    }

    public abstract String name();
}

然后我的Human类看起来像这样。

@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:   无法使用no调用公共com.service.example.models.Species()   ARGS

出于某种原因,我遇到了这个错误,我不明白发生了什么,有什么想法吗?

4 个答案:

答案 0 :(得分:2)

auto-value-gson并不支持您尝试实现的行为。

我假设你宣布你的改装服务返回Call<Species>,而只有Human.typeAdapter(Gson)注册到Gson。最后,Gson不知道如何实际创建Species的实例。

为了完成这项工作,您必须(创建并)为Species安装另一个类型适配器,它知道如何识别物种的实际子类型并将所有模型创建委托给特定类型适配器

答案 1 :(得分:2)

我确定你没有正确地GsonConverterFactory实例化。从my answer到您之前的问题:

@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();是最好的选择。

答案 2 :(得分:0)

你应该更喜欢组合而不是继承,因为至少目前在AutoValue中没有这样做。

请参阅github上的this issue

答案 3 :(得分:-1)

我通过从班级中删除解决了这个问题 抽象一词

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;
}