Set dynamic base url using Retrofit 2.0 and Dagger 2 Set dynamic base url using Retrofit 2.0 and Dagger 2 android android

Set dynamic base url using Retrofit 2.0 and Dagger 2


Support for this use-case was removed in Retrofit2. The recommendation is to use an OkHttp interceptor instead.

HostSelectionInterceptor made by swankjesse

import java.io.IOException;import okhttp3.HttpUrl;import okhttp3.Interceptor;import okhttp3.OkHttpClient;import okhttp3.Request;/** An interceptor that allows runtime changes to the URL hostname. */public final class HostSelectionInterceptor implements Interceptor {  private volatile String host;  public void setHost(String host) {    this.host = host;  }  @Override public okhttp3.Response intercept(Chain chain) throws IOException {    Request request = chain.request();    String host = this.host;    if (host != null) {      //HttpUrl newUrl = request.url().newBuilder()      //    .host(host)      //    .build();      HttpUrl newUrl = HttpUrl.parse(host);      request = request.newBuilder()          .url(newUrl)          .build();    }    return chain.proceed(request);  }  public static void main(String[] args) throws Exception {    HostSelectionInterceptor interceptor = new HostSelectionInterceptor();    OkHttpClient okHttpClient = new OkHttpClient.Builder()        .addInterceptor(interceptor)        .build();    Request request = new Request.Builder()        .url("http://www.coca-cola.com/robots.txt")        .build();    okhttp3.Call call1 = okHttpClient.newCall(request);    okhttp3.Response response1 = call1.execute();    System.out.println("RESPONSE FROM: " + response1.request().url());    System.out.println(response1.body().string());    interceptor.setHost("www.pepsi.com");    okhttp3.Call call2 = okHttpClient.newCall(request);    okhttp3.Response response2 = call2.execute();    System.out.println("RESPONSE FROM: " + response2.request().url());    System.out.println(response2.body().string());  }}

Or you can either replace your Retrofit instance (and possibly store the instance in a RetrofitHolder in which you can modify the instance itself, and provide the holder through Dagger)...

public class RetrofitHolder {   Retrofit retrofit;   //getter, setter}

Or re-use your current Retrofit instance and hack the new URL in with reflection, because screw the rules. Retrofit has a baseUrl parameter which is private final, therefore you can access it only with reflection.

Field field = Retrofit.class.getDeclaredField("baseUrl");field.setAccessible(true);okhttp3.HttpUrl newHttpUrl = HttpUrl.parse(newUrl);field.set(retrofit, newHttpUrl);


Retrofit2 library comes with a @Url annotation. You can override baseUrl like this:

API interface:

public interface UserService {      @GET    public Call<ResponseBody> profilePicture(@Url String url);}

And call the API like this:

Retrofit retrofit = Retrofit.Builder()      .baseUrl("https://your.api.url/");    .build();UserService service = retrofit.create(UserService.class);  service.profilePicture("https://s3.amazon.com/profile-picture/path");

For more details refer to this link: https://futurestud.io/tutorials/retrofit-2-how-to-use-dynamic-urls-for-requests


This worked for me in Kotlin

class HostSelectionInterceptor: Interceptor {    override fun intercept(chain: Interceptor.Chain): Response {        var request = chain.request()        val host: String = SharedPreferencesManager.getServeIpAddress()        val newUrl = request.url().newBuilder()            .host(host)            .build()        request = request.newBuilder()            .url(newUrl)            .build()        return chain.proceed(request)    }}

Add the interceptor to OkHttpClient builder

val okHttpClient = OkHttpClient.Builder()                .addInterceptor(HostSelectionInterceptor())                .cache(null)                .build()