Retrofit 2 — Share OkHttp Client and Converters between Retrofit Instances

Using Retrofit for your Android app's networking can make your life so much easier. However, Retrofit's design requires a single Retrofit instance for each API with a different base URL. Consequently, if your app is talking to two or more APIs (under different URLs), you'll need to deal with at least two Retrofit instances.

If you've multiple Retrofit instances and don't pay attention, you'll lose app performance. In this tutorial, we'll show you how you can share OkHttp as the HTTP network layer between the Retrofit instances, and prevent this loss of performance.

Retrofit Series Overview

Issue of Multiple Retrofit Instances

If your app uses multiple Retrofit instances, your declaration probably looks similar to this:

Retrofit retrofitApiV1 = new Retrofit.Builder()  
        .baseUrl("https://futurestud.io/v1/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

Retrofit retrofitApiV2 = new Retrofit.Builder()  
        .baseUrl("https://futurestud.io/v2/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

The example code above uses the same domain, but it could also be two completely different domains, or just different subdomains. In either case, with the example code Retrofit would create a new OkHttp instance for each Retrofit instance. This default behavior leads to at least two separate OkHttp instances, which each keep their own request pooling, disk cache, routing logic, etc.. Because they don't share these, your overall app will unnecessarily lose performance.

Solution 1: Sharing Default OkHttp Instance

In order to make them share a single OkHttp instance, you can simply pass it explicitly on the builder:

OkHttpClient okHttpClient = new OkHttpClient();

Retrofit retrofitApiV1 = new Retrofit.Builder()  
        .baseUrl("https://futurestud.io/v1/")
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

Retrofit retrofitApiV2 = new Retrofit.Builder()  
        .baseUrl("https://futurestud.io/v2/")
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

The small difference in the new code above causes a shared OkHttp instance and you win back the lost app performance.

If you need two different instances of the OkHttp client, the next section is for you.

Solution 2: Sharing Modified OkHttp Instances

Of course, our example code is simplified. You might already have custom OkHttp clients in your app. Are you stuck when the different APIs you need to talk to require each a custom OkHttp client, e.g., by having different interceptors?

No! You can still share the core (request pooling, disk cache, …) of the OkHttp client between all instances. In order to create custom OkHttp clients, but with a shared core, you can make shallow copies of an OkHttp client by calling .newBuilder():

// core will be shared across both clients
OkHttpClient baseOkHttpClient = new OkHttpClient();

// customize client for first Retrofit instance for API v1
OkHttpClient okHttpClientV1 = baseOkHttpClient  
        .newBuilder()
        .followRedirects(false)
        .build()

Retrofit retrofitApiV1 = new Retrofit.Builder()  
        .baseUrl("https://futurestud.io/v1/")
        .client(okHttpClientV1)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

// customize client for second Retrofit instance for API v2
OkHttpClient okHttpClientV2 = baseOkHttpClient  
        .newBuilder()
        .addInterceptor(...)
        .build()

Retrofit retrofitApiV2 = new Retrofit.Builder()  
        .baseUrl("https://futurestud.io/v2/")
        .client(okHttpClientV2)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

This way, you can customize each OkHttp client to the specific needs, including interceptors. okHttpClientV1 and okHttpClientV2 are customized to the needs of their respective API, but still use the same core. Sharing an OkHttp (core) instance across Retrofit clients can be particularly effective when the servers use HTTP/2, where additional advantages come into play when the APIs live physically on the same server.

Converters

Beware, the negative effect of not sharing resources is also happening (with a less dramatic effect) for converters. For example, this is the code we've shown you above:

OkHttpClient okHttpClient = new OkHttpClient();

Retrofit retrofitApiV1 = new Retrofit.Builder()  
        .baseUrl("https://futurestud.io/v1/")
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

Retrofit retrofitApiV2 = new Retrofit.Builder()  
        .baseUrl("https://futurestud.io/v2/")
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

Here, we're creating two Gson instances by separately calling GsonConverterFactory.create(). That means those two instances won't share any cache with each other. Instead, you should pass the same Gson (factory) instance to the two Retrofit instances:

GsonConverterFactory gsonFactory = GsonConverterFactory.create();  
OkHttpClient okHttpClient = new OkHttpClient();

Retrofit retrofitApiV1 = new Retrofit.Builder()  
        .baseUrl("https://futurestud.io/v1/")
        .client(okHttpClient)
        .addConverterFactory(gsonFactory)
        .build();

Retrofit retrofitApiV2 = new Retrofit.Builder()  
        .baseUrl("https://futurestud.io/v2/")
        .client(okHttpClient)
        .addConverterFactory(gsonFactory)
        .build();

Don't forget to optimize your app's performance with these small details!

Summary

In this tutorial you've learned that it's important to share the OkHttp instance, or at least its core, and converters between various Retrofit instances. This optimizes your app's performance with a very little implementation detail!

Do you have further questions on this topic or about Retrofit in general? Just let us know on Twitter @futurestud_io or leave a comment below.

Enjoy coding & make it rock!


Additional Resources

Explore the Library

Find interesting tutorials and solutions for your problems.