Utiliser TokenAuthenticatorune réponse comme @theblang est une manière correcte de gérer refresh_token.
Voici mon outil (j'utilise Kotlin, Dagger, RX mais vous pouvez utiliser cette idée pour implémenter votre cas)
TokenAuthenticator
class TokenAuthenticator @Inject constructor(private val noneAuthAPI: PotoNoneAuthApi, private val accessTokenWrapper: AccessTokenWrapper) : Authenticator {
    override fun authenticate(route: Route, response: Response): Request? {
        val newAccessToken = noneAuthAPI.refreshToken(accessTokenWrapper.getAccessToken()!!.refreshToken).blockingGet()
        accessTokenWrapper.saveAccessToken(newAccessToken) // save new access_token for next called
        return response.request().newBuilder()
                .header("Authorization", newAccessToken.token) // just only need to override "Authorization" header, don't need to override all header since this new request is create base on old request
                .build()
    }
}
Pour éviter le cycle de dépendance comme le commentaire @Brais Gabin, je crée 2 interfaces comme
interface PotoNoneAuthApi { // NONE authentication API
    @POST("/login")
    fun login(@Body request: LoginRequest): Single<AccessToken>
    @POST("refresh_token")
    @FormUrlEncoded
    fun refreshToken(@Field("refresh_token") refreshToken: String): Single<AccessToken>
}
et
interface PotoAuthApi { // Authentication API
    @GET("api/images")
    fun getImage(): Single<GetImageResponse>
}
AccessTokenWrapper classe 
class AccessTokenWrapper constructor(private val sharedPrefApi: SharedPrefApi) {
    private var accessToken: AccessToken? = null
    // get accessToken from cache or from SharePreference
    fun getAccessToken(): AccessToken? {
        if (accessToken == null) {
            accessToken = sharedPrefApi.getObject(SharedPrefApi.ACCESS_TOKEN, AccessToken::class.java)
        }
        return accessToken
    }
    // save accessToken to SharePreference
    fun saveAccessToken(accessToken: AccessToken) {
        this.accessToken = accessToken
        sharedPrefApi.putObject(SharedPrefApi.ACCESS_TOKEN, accessToken)
    }
}
AccessToken classe
data class AccessToken(
        @Expose
        var token: String,
        @Expose
        var refreshToken: String)
Mon intercepteur
class AuthInterceptor @Inject constructor(private val accessTokenWrapper: AccessTokenWrapper): Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()
        val authorisedRequestBuilder = originalRequest.newBuilder()
                .addHeader("Authorization", accessTokenWrapper.getAccessToken()!!.token)
                .header("Accept", "application/json")
        return chain.proceed(authorisedRequestBuilder.build())
    }
}
Enfin, ajoutez Interceptoret Authenticatorà votre OKHttpClientlors de la création du service PotoAuthApi
Démo
https://github.com/PhanVanLinh/AndroidMVPKotlin
Remarque
Flux d'authentificateur
- Exemple de getImage()code d'erreur de retour d' API 401
- authenticatela méthode à l'intérieur- TokenAuthenticatorsera tirée
- Synchroniser noneAuthAPI.refreshToken(...)appelé
- Après la noneAuthAPI.refreshToken(...)réponse -> un nouveau jeton s'ajoutera à l'en-tête
- getImage()sera AUTO appelé avec un nouvel en-tête (- HttpLoggingne journalisera pas cet appel) (à l'- interceptintérieur- AuthInterceptorne sera pas appelé )
- Si - getImage()toujours échoué avec l'erreur 401, la- authenticateméthode à l'intérieur- TokenAuthenticatorsera déclenchée à NOUVEAU et à NOUVEAU, puis elle lancera une erreur sur la méthode d'appel plusieurs fois (- java.net.ProtocolException: Too many follow-up requests). Vous pouvez l'empêcher en comptant la réponse . Par exemple, si vous- return nullen- authenticateaprès 3 fois nouvelle tentative,- getImage()va finir et- return response 401
 
- Si - getImage()réponse réussie => nous obtiendrons le résultat normalement (comme vous appelez- getImage()sans erreur)
 
J'espère que ça aide