これが私の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
フィールドのみをマップします。コンバーターを作成してTextMessage
およびImageMessage
オブジェクトを作成し、一致するすべてのフィールドをマップしてからAbstractMessage
にキャストするにはどうすればよいですか。または、他の解決策があるかもしれません。
オブジェクトAbstractMessage、TextMessage、およびImageMessageに対して 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();
クラス RuntimeTypeAdapterFactory.Java はGsonパッケージに同梱されていないため、手動でダウンロードする必要があります。
ランタイムアダプタの詳細を読むことができます ここ および ここ
質問のタイトルは「Gsonによるポリモーフィズム」である必要があることに注意してください
お役に立てば幸いです。