Set dynamic base url using Retrofit 2.0 and Dagger 2

前端 未结 8 594
南旧
南旧 2020-11-27 12:36

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         


        
8条回答
  •  伪装坚强ぢ
    2020-11-27 12:45

    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);
    

提交回复
热议问题