簡體   English   中英

多態性如何與Gson(Retrofit)協同工作

[英]How does Polymorphism work with Gson (Retrofit)

這是我的Retrofit實例:

@Provides
@Singleton
ApiManager provideApiManager() {
    RxJava2CallAdapterFactory rxAdapter = RxJava2CallAdapterFactory.create();

    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addNetworkInterceptor(new StethoInterceptor())
            .build();

    Gson gson = new GsonBuilder().create();
    GsonConverterFactory converterFactory = GsonConverterFactory.create(gson);

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(AppConstants.BASE_URL)
            .addConverterFactory(converterFactory)
            .addCallAdapterFactory(rxAdapter)
            .client(okHttpClient)
            .build();
    return retrofit.create(ApiManager.class);
}

模型:

class AbstractMessage {
    String id;
}

class TextMessage extends AbstractMessage {
    String textMessage;
}

class ImageMessage extends AbstractMessage {
    String url;
    String text;
}

請求:

@GET("direct/messages")
Observable<List<AbstractMessage>> getMessages(@Header("Authorization") String authHeader, @Body RequestObject request);   

執行請求:

apiManager.getMessages(authHeader, requestObject)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Consumer<List<AbstractMessage>>() {
        @Override
        public void accept(List<AbstractMessage> messages) throws Exception {
            ...
        }
    });

當我執行一個請求時,我收到了一個AbstractMessage對象的集合。 JSON可以包含文本和圖像消息。 在我的例子中, JSON轉換器創建AbstractMessage並僅映射id字段。 如何使轉換器創建TextMessageImageMessage對象映射所有匹配的字段,然后將其ImageMessage轉換為AbstractMessage 或者可能還有其他一些解決方案。

您必須為對象AbstractMessage,TextMessage和ImageMes​​sage創建RuntimeTypeAdapterFactory ,然后必須將其設置為gson實例。

假設你有這些對象:

public class Animal {
    protected String name;
    protected String type;

    public Animal(String name, String type) {
        this.name = name;
        this.type = type;
    }
}

public class Dog extends Animal {
    private boolean playsCatch;

    public Dog(String name, boolean playsCatch) {
        super(name, "dog");
        this.playsCatch = playsCatch;
    }
}

public class Cat extends Animal {
    private boolean chasesLaser;

    public Cat(String name, boolean chasesLaser) {
        super(name, "cat");
        this.chasesLaser = chasesLaser;
    }
}

下面是您需要的RuntimeTypeAdapter ,以便正確地反序列化(和序列化)這些對象:

RuntimeTypeAdapterFactory<Animal> runtimeTypeAdapterFactory = RuntimeTypeAdapterFactory
    .of(Animal.class, "type")
    .registerSubtype(Dog.class, "dog")
    .registerSubtype(Cat.class, "cat");

Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(runtimeTypeAdapterFactory)
    .create();

RunsonTypeAdapterFactory.java類不隨Gson包一起提供,因此您必須手動下載它。

您可以在此處此處閱讀有關運行時適配器的更多信息

請注意,你的問題的標題應該是“與Gson的多態性”

我希望它有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM