I\'m trying to perform a login action using Retrofit 2.0 using Dagger 2
Here\'s how I set up Retrofit dependency
@Provides
@Singleton
Retrofit provid         
        For latest Retrofit library, you can simply use singleton instance and change it with retrofitInstance.newBuilder().baseUrl(newUrl). No need to create another instance.
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);
                                                                        Please look into my workaround for Dagger dynamic URL.
Step1: Create an Interceptor
import android.util.Patterns;
import com.nfs.ascent.mdaas.repo.network.ApiConfig;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class DomainURLInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request original = chain.request();
        String requestUrl = original.url().toString();
        String PROTOCOL = "(?i:http|https|rtsp)://";
        String newURL = requestUrl.replaceFirst(PROTOCOL, "")
                .replaceFirst(Patterns.DOMAIN_NAME.toString(), "");
        newURL = validateBackSlash(newURL) ? ApiConfig.BASE_URL.concat(newURL) : newURL.replaceFirst("/", ApiConfig.BASE_URL);
        original = original.newBuilder()
                .url(newURL)
                .build();
        return chain.proceed(original);
    }
    private boolean validateBackSlash(String str) {
        if (!str.substring(str.length() - 1).equals("/")) {
            return true;
        }
        return false;
    }
}
Step 2:
add your newly created interceptor in your module
    @Provides
    @Singlton
    DomainURLInterceptor getChangeURLInterceptor() {
        return new DomainURLInterceptor();
    }
step 3: add interceptor into list of HttpClient interceptors
    @Provides
    @Singlton
    OkHttpClient provideHttpClient() {
        return new OkHttpClient.Builder()
                .addInterceptor(getChangeURLInterceptor())
                .readTimeout(ApiConfig.API_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
                .connectTimeout(ApiConfig.API_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
                .build();
    }
step 4:
    @Provides
    @Singlton
    Retrofit provideRetrofit() {
        return new Retrofit.Builder()
                .baseUrl(ApiConfig.BASE_URL) // this is default URl,
                .addConverterFactory(provideConverterFactory())
                .client(provideHttpClient())
                .build();
    }
Note: if the user has to change the Base URL from settings, remember to validate the newly created URL with below method:
    public final static boolean isValidUrl(CharSequence target) {
        if (target == null) {
            return false;
        } else {
            return Patterns.WEB_URL.matcher(target).matches();
        }
    }
                                                                        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()
                                                                        You are able to instantiate new object using un-scoped provide method.
@Provides
LoginAPI provideAPI(Gson gson, OkHttpClient client, BaseUrlHolder baseUrlHolder) {
    Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create(gson)
                        .client(client)
                        .baseUrl(baseUrlHolder.get())
                        .build();
    return retrofit.create(LoginAPI.class);     
}
@AppScope
@Provides
BaseUrlHolder provideBaseUrlHolder() {
    return new BaseUrlHolder("https://www.default.com")
}
public class BaseUrlHolder {
    public String baseUrl;
    public BaseUrlHolder(String baseUrl) {
        this.baseUrl = baseUrl;
    }
    public String getBaseUrl() {
        return baseUrl;
    }
    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }
}
Now you can change base url via getting baseUrlHolder from the component
App.appComponent.getBaseUrlHolder().set("https://www.changed.com");
this.loginApi = App.appComponent.getLoginApi();
                                                                        Thanks to @EpicPandaForce for help. If someone is facing IllegalArgumentException, this is my working code.
public class HostSelectionInterceptor implements Interceptor {
    private volatile String host;
    public void setHost(String host) {
        this.host = HttpUrl.parse(host).host();
    }
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        String reqUrl = request.url().host();
        String host = this.host;
        if (host != null) {
            HttpUrl newUrl = request.url().newBuilder()
                .host(host)
                .build();
            request = request.newBuilder()
                .url(newUrl)
                .build();
        }
        return chain.proceed(request);
    }
}