Comment fonctionne le polymorphism avec Gson (Retrofit)

Voici mon instance de mise à niveau:

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

Modèle:

 class AbstractMessage { Ssortingng id; } class TextMessage extends AbstractMessage { Ssortingng textMessage; } class ImageMessage extends AbstractMessage { Ssortingng url; Ssortingng text; } 

Demande:

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

Demande d’exécution:

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

Lorsque j’exécute une demande, je reçois une collection d’objects AbstractMessage . Le JSON peut contenir des messages texte et image. Dans mon cas, le convertisseur JSON crée AbstractMessage et mappe uniquement le champ id . Comment créer un convertisseur pour créer des objects TextMessage et ImageMessage tous les champs correspondants, puis les ImageMessage en AbstractMessage . Ou il peut y avoir une autre solution.

Vous devez créer un RuntimeTypeAdapterFactory pour les objects AbstractMessage, TextMessage et ImageMessage, puis vous devez le définir dans l’instance gson.

Supposons que vous ayez ces objects:

 public class Animal { protected Ssortingng name; protected Ssortingng type; public Animal(Ssortingng name, Ssortingng type) { this.name = name; this.type = type; } } public class Dog extends Animal { private boolean playsCatch; public Dog(Ssortingng name, boolean playsCatch) { super(name, "dog"); this.playsCatch = playsCatch; } } public class Cat extends Animal { private boolean chasesLaser; public Cat(Ssortingng name, boolean chasesLaser) { super(name, "cat"); this.chasesLaser = chasesLaser; } } 

Voici ci-dessous le RuntimeTypeAdapter dont vous avez besoin pour désérialiser (et sérialiser) correctement ces objects:

 RuntimeTypeAdapterFactory runtimeTypeAdapterFactory = RuntimeTypeAdapterFactory .of(Animal.class, "type") .registerSubtype(Dog.class, "dog") .registerSubtype(Cat.class, "cat"); Gson gson = new GsonBuilder() .registerTypeAdapterFactory(runtimeTypeAdapterFactory) .create(); 

La classe RuntimeTypeAdapterFactory.java n’est pas livrée avec le package Gson. Vous devez donc la télécharger et l’append manuellement à votre projet.

Vous pouvez en savoir plus sur l’adaptateur d’exécution ici et ici

Veuillez noter que le titre de votre question devrait être “Polymorphisme avec Gson”

J’espère que ça aide.