AutoValue Gson Extension with Retrofit 2.0

AutoValue is a great library to create value types in java. It also helps to reduce the boilerplate code involved with creating value types. While working with Api calls and modeling your data model, there is a lot of repetitive work. AutoValue helps you to overcome this using Annotation Processing and code generation.

“AutoValue is a great tool for eliminating the drudgery of writing mundane value classes in Java. It encapsulates much of the advice in Effective Java Chapter 2, and frees you to concentrate on the more interesting aspects of your program. The resulting program is likely to be shorter, clearer, and freer of bugs. Two thumbs up.”
Joshua Bloch, author, Effective Java

AutoValue’s Gson(make sure to add the Gson dependency) extension is an great addition to the AutoValue library to handle json parsing. Below I explain how to use AutoValue’s Gson extension to make Api calls using Retrofit 2.0:

Add Retrofit dependencies to your Gradle file

compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

Add AutoValue dependencies

provided 'com.google.auto.value:auto-value:1.2'
annotationProcessor 'com.google.auto.value:auto-value:1.2'

Add gson extension for AutoValue

annotationProcessor 'com.ryanharter.auto.value:auto-value-gson:0.4.5'
provided 'com.ryanharter.auto.value:auto-value-gson:0.4.5'

To use AutoValue all you need to do is Add the “@AutoValue” annotation to the class and create abstract methods for member variables. AutoValue takes cares of the rest, it even creates the equals, hashCode and toString methods.

The typeAdapter(Gson gson) is required to handle the gson parsing.

Sample model class using AutoValue (This is a great json converter plugin for Android Studio, it also has AutoValue support):

@AutoValue 
public abstract class MovieWrapper {

@SerializedName("page")
public abstract int page();

@SerializedName("results")
public abstract List<Movie> results();

@SerializedName("dates")
public abstract Dates dates();

@SerializedName("total_pages")
abstract int totalPages();

@SerializedName("total_results")
abstract int totalResults();

public static TypeAdapter<MovieWrapper> typeAdapter(Gson gson) {
return new AutoValue_MovieWrapper.GsonTypeAdapter(gson);
}
}

To generate a TypeAdapterFactory for all of your auto-value-gson classes, simply create an abstract class that implements TypeAdapterFactory and annotate it with @GsonTypeAdapterFactory, and auto-value-gson will create an implementation for you.

Create the below Factory class to handle parsing of classes created using AutoValue

@GsonTypeAdapterFactory
public abstract class AutoValueGsonFactory implements TypeAdapterFactory {

// Static factory method to access the package
// private generated implementation
public static TypeAdapterFactory create() {
return new AutoValueGson_AutoValueGsonFactory();
}
}

Create GsonConverterFactory and register the above created Factory

GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create(
new GsonBuilder().registerTypeAdapterFactory(AutoValueGsonFactory.create())
.create());

Register the above created GsonConverterFactory in your Retrofit client

Retrofit retrofitClient = new Retrofit.Builder()
.baseUrl(BuildConfig.END_POINT)
.addConverterFactory(gsonConverterFactory)
.client(okHttpClient.build())
.build();

Thats it!! You should be able to use your retrofit client now to parse the AutoValue classes using gson.

Sample Github Project