问题 
  
 
我需要从USER输入的域中调用API,我需要在调用插入数据之前编辑我的Retrofit单例.
有没有办法“重置”我的单身人士,迫使它重新创建?
要么
有没有办法在调用之前用我的数据(可能在Interceptor中)更新我的baseUrl?
码
单身
@Provides
@Singleton
Retrofit provideRetrofit(SharedPreferences prefs) {
    String apiUrl = "https://%1s%2s";
    apiUrl = String.format(apiUrl,prefs.getString(ACCOUNT_SUBDOMAIN,null),prefs.getString(ACCOUNT_DOMAIN,null));
    OkHttpClient httpClient = new OkHttpClient.Builder()
            .addInterceptor(new HeaderInterceptor())
            .build();
    return new Retrofit.Builder()
            .baseUrl(apiUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .client(httpClient)
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();
}
@Provides
@Singleton
API provideAPI(Retrofit retrofit) {
    return retrofit.create(API.class);
} 
 API
@FormUrlEncoded
@POST("endpoint")
Observable<Response> logIn(@Field("login") String login,@Field("password") String password); 
 它现在如何运作
好的想法是在API调用之前通过SharedPrefs保存用户域数据,并使用格式化的String修改baseUrl.
解决方法
 我在这里看到2个选项: 
  
 
        >按照预期使用匕首.为每个baseUrl创建自己的Retrofit客户端,或者
>在发送请求之前使用拦截器修改请求
匕首的方法
如果您使用暴力网址,这可能不是正确的选择,因为它依赖于为每个网站创建一个新的Retrofit实例.
现在每次网址更改时,您只需通过为其提供新的UrlModule来重新创建以下演示的UrlComponent.
清理
清理你的@Singleton模块,以便它提供GsonConverterFactory和RxJavaCallAdapterFactory以正确使用dagger而不重新创建共享对象.
@Module
public class SingletonModule {
  @Provides
  @Singleton
  GsonConverterFactory provideOkHttpClient() {/**/}
  @Provides
  @Singleton
  RxJavaCallAdapterFactory provideOkHttpClient() {/**/}
}
@Singleton
@Component(modules = SingletonModule.class)
interface SingletonComponent {
    // sub component
    UrlComponent plus(UrlModule component);
} 
 Url Scoped
引入@UrlScope来扩展您的Retrofit实例.
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface UrlScope {
} 
 然后创建一个子组件
@SubComponent(modules=UrlModule.class)
public interface UrlComponent {} 
 还有一个模块
@Module
class UrlModule {
    private final String mUrl;
    UrlModule(String url) { mUrl = url; }
    @Provides
    String provideUrl() {
        return mUrl;
    }
    @Provides
    @UrlScope
    OkHttpClient provideOkHttpClient(String url) {
        return new OkHttpClient.Builder().build();
    }
    @Provides
    @UrlScope
    Retrofit provideRetrofit(OkHttpClient client) {
        return new Retrofit.Builder().build();
    }
} 
 使用范围改造
实例化组件并使用它.
class Dagger {
    public void demo() {
        UrlModule module = new UrlModule(/*some url*/);
        SingletonComponent singletonComponent = DaggerSingletonComponent.create();
        UrlComponent urlComponent = singletonComponent.plus(module);
        urlComponent.getRetrofit(); // done.
    }
} 
 OkHttp方法
提供适当范围的拦截器(在本例中为@Singleton)并实现相应的逻辑.
@Module
class SingletonModule {
    @Provides
    @Singleton
    GsonConverterFactory provideGsonConverter() { /**/ }
    @Provides
    @Singleton
    RxJavaCallAdapterFactory provideRxJavaCallAdapter() { /**/ }
    @Provides
    @Singleton
    MyApiInterceptor provideMyApiInterceptor() { /**/ }
    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient(MyApiInterceptor interceptor) {
        return new OkHttpClient.Builder().build();
    }
    @Provides
    @Singleton
    Retrofit provideRetrofit(OkHttpClient client) {
        return new Retrofit.Builder().build();
    }
}
@Singleton
@Component(modules = SingletonModule.class)
interface SingletonComponent {
    Retrofit getRetrofit();
    MyApiInterceptor getInterceptor();
} 
 todo实现MyApiInterceptor.您将需要为基本URL设置一个setter,然后只需重写/修改通过的请求.
然后,再次,继续使用它.
class Dagger {
    public void demo() {
        SingletonComponent singletonComponent = DaggerSingletonComponent.create();
        MyService service = singletonComponent.getRetrofit().create(MyService.class);
        MyApiInterceptor interceptor = singletonComponent.getInterceptor();
        interceptor.setBaseUrl(myUrlA);
        service.doA();
        interceptor.setBaseUrl(someOtherUrl);
        service.dob();
    }
} 
 作为第三种方法,您还可以使用反射直接更改基本URL – 我为了完整性而添加了最后一个.