Reputation: 4391
I have a large json which i have to deserialize, and i'm only interested of certain parts of if. The Pojos i am using are something like this:
data class Response<T>(
val header: JHeader,
val result: T
)
data class JHeader(
val success: Int,
val error: List<String>
)
class Character{
@SerializedName("id_") val id: Int
@SerializedName("levelA") val level: String
@SerializedName("a3") val unit: String = ""
constructor(id: Int, level: String) {
this.id = id
this.level= level
}
}
Relevant part of the retrofit adapter:
val retrofit = Retrofit.Builder()
.addCallAdapterFactory(rxAdapter)
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.client(httpClient.build())
.build()
And the Impl:
fun getCharacterById(characterID: Int):Observable<Response<List<Character>>> {
return apiService.getCharacter(characterID)
.subscribeOn(Schedulers.io())
}
I'm getting retrofit debug reports of 300ms for a simple call to this service.
My questions are:
When should i consider using a TypeAdapter (i opt for performance over boilerplate, i dont mind writing a few extra lines of code with type adapters). But I don't quite understand what type adapters are for, in what scenarios should i use them.
My Json structure has a lot more attributes than my Character Pojo, i simply realised that using transient / @Expose or keeping it out of the Pojo lead to the same results. Is there any difference between those 3?
As i'm using Kotlin, is there any library/extension that help me deal with this TypeAdapter deserialization stuff?
Upvotes: 3
Views: 1883
Reputation: 894
For me implementing a custom TypeAdapter
was a huge performance boost. I use type adapters for every class which needs to be deserialized in huge amounts. In your example that would be (in Java):
public class CharacterTypeAdapter extends TypeAdapter<Character> {
@Override
public void write(final JsonWriter out, final Character character) throws IOException {
out.beginObject();
out.name("id").value(character.getId());
out.name("level").value(character.getLevel());
out.name("unit").value(character.getUnit());
out.endObject();
}
@Override
public Character read(final JsonReader in) throws IOException {
Character character = new Character();
in.beginObject();
while(in.hasNext()){
switch(in.nextName()){
case "id":
character.setId(in.nextInt());
break;
case "level":
character.setId(in.nextString());
break;
case "unit":
character.setId(in.nextString());
break;
}
}
in.endObject();
return character;
}
}
The TypeAdapter
must be registered in your Gson configuration as follows:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Character.class, new CharacterTypeAdapter());
Gson gson = gsonBuilder.create();
The gson instance must be registered with Retrofit:
new Retrofit
.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
.createApi(Api.class);
You get blazing fast deserialization.
Upvotes: 2