2017-04-08 21 views
-1

我有這樣的基本抽象類。繼承與改造未能調用,沒有參數

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: 失敗,但沒有 參數傳遞給調用公共com.service.example.models.Species()

由於某種原因,但我得到這個錯誤,我不明白髮生了什麼,有什麼想法?

+0

您是否添加了基於'Gson'配置的'GsonConverterFactory'在構建'Retrofit'實例時,我在您之前的問題中暗示您? –

+0

是的,我有,不知道發生了什麼,我可能會錯過一些東西。 – Claud

+0

您能否提供構建Gson和Retrofit實例的代碼? –

回答

0

您應該更喜歡構圖而不是繼承,因爲至少目前在AutoValue中沒有這樣做。

在github上查看this issue

2

auto-value-gson不支持您嘗試實現的行爲。

我假設你宣佈你的改造服務返回Call<Species>,而只有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(); 

配置的改造實例這個:

new Retrofit.Builder() 
     ... 
     .addConverterFactory(GsonConverterFactory.create(gson)) // THIS is necessary 
     .build(); 

確保您的服務接口運行在HumanSpecies

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();是最好的選擇這裏。