【问题标题】:Inheritance with Retrofit failed to invoke, with no argsRetrofit 的继承调用失败,没有参数
【发布时间】:2017-04-08 13:28:59
【问题描述】:

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

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: 无法调用公共 com.service.example.models.Species() 没有 参数

但是由于某种原因,我收到了这个错误,我不明白发生了什么,知道吗?

【问题讨论】:

  • 您是否在构建Retrofit 实例时基于Gson 配置添加了GsonConverterFactory
  • 是的,我有,但不确定发生了什么,我可能遗漏了一些东西。
  • 能否提供构建 Gson 和 Retrofit 实例的代码?

标签: android gson retrofit auto-value


【解决方案1】:

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

我假设您声明您的改造服务返回 Call&lt;Species&gt;,而只有 Human.typeAdapter(Gson) 注册到 Gson。这在 Gson 不知道如何实际创建 Species 的实例中得出结论。

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

【讨论】:

    【解决方案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();
    

    并且配置Retrofit实例这样:

    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&lt;Human&gt; getHuman(); 是这里的最佳选择。

    【讨论】:

      【解决方案3】:

      您应该更喜欢组合而不是继承,因为至少目前在 AutoValue 中无法做到这一点。

      在 github 上查看 this issue

      【讨论】:

        【解决方案4】:

        我通过从班级中删除解决了这个问题 摘要这个词

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-03
          相关资源
          最近更新 更多