android – Dagger Retrofit动态URL

前端之家收集整理的这篇文章主要介绍了android – Dagger Retrofit动态URL前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
问题

我需要从USER输入的域中调用API,我需要在调用插入数据之前编辑我的Retrofit单例.

有没有办法“重置”我的单身人士,迫使它重新创建?

要么

有没有办法在调用之前用我的数据(可能在Interceptor中)更新我的baseUrl?

单身

  1. @Provides
  2. @Singleton
  3. Retrofit provideRetrofit(SharedPreferences prefs) {
  4.  
  5. String apiUrl = "https://%1s%2s";
  6. apiUrl = String.format(apiUrl,prefs.getString(ACCOUNT_SUBDOMAIN,null),prefs.getString(ACCOUNT_DOMAIN,null));
  7.  
  8. OkHttpClient httpClient = new OkHttpClient.Builder()
  9. .addInterceptor(new HeaderInterceptor())
  10. .build();
  11.  
  12. return new Retrofit.Builder()
  13. .baseUrl(apiUrl)
  14. .addConverterFactory(GsonConverterFactory.create())
  15. .client(httpClient)
  16. .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
  17. .build();
  18. }
  19.  
  20. @Provides
  21. @Singleton
  22. API provideAPI(Retrofit retrofit) {
  23. return retrofit.create(API.class);
  24. }

API

  1. @FormUrlEncoded
  2. @POST("endpoint")
  3. 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而不重新创建共享对象.

  1. @Module
  2. public class SingletonModule {
  3.  
  4. @Provides
  5. @Singleton
  6. GsonConverterFactory provideOkHttpClient() {/**/}
  7.  
  8. @Provides
  9. @Singleton
  10. RxJavaCallAdapterFactory provideOkHttpClient() {/**/}
  11. }
  12.  
  13.  
  14. @Singleton
  15. @Component(modules = SingletonModule.class)
  16. interface SingletonComponent {
  17.  
  18. // sub component
  19. UrlComponent plus(UrlModule component);
  20. }

Url Scoped

引入@UrlScope来扩展您的Retrofit实例.

  1. @Scope
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface UrlScope {
  4. }

然后创建一个子组件

  1. @SubComponent(modules=UrlModule.class)
  2. public interface UrlComponent {}

还有一个模块

  1. @Module
  2. class UrlModule {
  3.  
  4. private final String mUrl;
  5.  
  6. UrlModule(String url) { mUrl = url; }
  7.  
  8. @Provides
  9. String provideUrl() {
  10. return mUrl;
  11. }
  12.  
  13. @Provides
  14. @UrlScope
  15. OkHttpClient provideOkHttpClient(String url) {
  16. return new OkHttpClient.Builder().build();
  17. }
  18.  
  19. @Provides
  20. @UrlScope
  21. Retrofit provideRetrofit(OkHttpClient client) {
  22. return new Retrofit.Builder().build();
  23. }
  24.  
  25. }

使用范围改造

实例化组件并使用它.

  1. class Dagger {
  2.  
  3. public void demo() {
  4. UrlModule module = new UrlModule(/*some url*/);
  5. SingletonComponent singletonComponent = DaggerSingletonComponent.create();
  6. UrlComponent urlComponent = singletonComponent.plus(module);
  7.  
  8. urlComponent.getRetrofit(); // done.
  9. }
  10. }

OkHttp方法

提供适当范围的拦截器(在本例中为@Singleton)并实现相应的逻辑.

  1. @Module
  2. class SingletonModule {
  3.  
  4. @Provides
  5. @Singleton
  6. GsonConverterFactory provideGsonConverter() { /**/ }
  7.  
  8. @Provides
  9. @Singleton
  10. RxJavaCallAdapterFactory provideRxJavaCallAdapter() { /**/ }
  11.  
  12. @Provides
  13. @Singleton
  14. MyApiInterceptor provideMyApiInterceptor() { /**/ }
  15.  
  16. @Provides
  17. @Singleton
  18. OkHttpClient provideOkHttpClient(MyApiInterceptor interceptor) {
  19. return new OkHttpClient.Builder().build();
  20. }
  21.  
  22. @Provides
  23. @Singleton
  24. Retrofit provideRetrofit(OkHttpClient client) {
  25. return new Retrofit.Builder().build();
  26. }
  27. }
  28.  
  29. @Singleton
  30. @Component(modules = SingletonModule.class)
  31. interface SingletonComponent {
  32.  
  33. Retrofit getRetrofit();
  34.  
  35. MyApiInterceptor getInterceptor();
  36. }

todo实现MyApiInterceptor.您将需要为基本URL设置一个setter,然后只需重写/修改通过的请求.

然后,再次,继续使用它.

  1. class Dagger {
  2.  
  3. public void demo() {
  4. SingletonComponent singletonComponent = DaggerSingletonComponent.create();
  5. MyService service = singletonComponent.getRetrofit().create(MyService.class);
  6. MyApiInterceptor interceptor = singletonComponent.getInterceptor();
  7.  
  8. interceptor.setBaseUrl(myUrlA);
  9. service.doA();
  10. interceptor.setBaseUrl(someOtherUrl);
  11. service.doB();
  12. }
  13. }

作为第三种方法,您还可以使用反射直接更改基本URL – 我为了完整性而添加了最后一个.

猜你在找的Android相关文章