【问题标题】:Dagger2, providing Retrofit instances with different APIs same timeDagger2,同时提供不同API的Retrofit实例
【发布时间】:2016-10-06 17:57:28
【问题描述】:

在我的项目中,我使用 Retrofit 并尝试使用 Dagger 来注入依赖项。我还有 2 个具有不同 API 的改造服务。我需要同时使用 2 个具有不同 baseUrls 的不同 API。我卡在这里,不知道下一步该怎么做。

我的应用程序模块:

@Module
public class ApplicationModule {

private String FIRST_API_URL = "https://first-api.com";
private String SECOND_API_URL = "https://second-api.com";

private String mBaseUrl;
private Context mContext;

public ApplicationModule(Context context) {
    mContext = context;
}

@Singleton
@Provides
GsonConverterFactory provideGsonConverterFactory() {
    return GsonConverterFactory.create();
}

@Singleton
@Provides
@Named("ok-1")
OkHttpClient provideOkHttpClient1() {
    return new OkHttpClient.Builder()
            .connectTimeout(20, TimeUnit.SECONDS)
            .readTimeout(20, TimeUnit.SECONDS)
            .build();
}

@Singleton
@Provides
@Named("ok-2")
OkHttpClient provideOkHttpClient2() {
    return new OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .build();
}

@Singleton
@Provides
RxJavaCallAdapterFactory provideRxJavaCallAdapterFactory() {
    return RxJavaCallAdapterFactory.create();
}

@Singleton
@Provides
@FirstApi
Retrofit provideRetrofit(@Named("ok-1") OkHttpClient client, GsonConverterFactory converterFactory, RxJavaCallAdapterFactory adapterFactory) {
    return new Retrofit.Builder()
            .baseUrl(FIRST_API_URL)
            .addConverterFactory(converterFactory)
            .addCallAdapterFactory(adapterFactory)
            .client(client)
            .build();
}

@Singleton
@Provides
@SecondApi
Retrofit provideRetrofit2(@Named("ok-1") OkHttpClient client, GsonConverterFactory converterFactory, RxJavaCallAdapterFactory adapterFactory) {
    return new Retrofit.Builder()
            .baseUrl(SECOND_API_URL)
            .addConverterFactory(converterFactory)
            .addCallAdapterFactory(adapterFactory)
            .client(client)
            .build();
}

@Provides
@Singleton
Context provideContext() {
    return mContext;
}
}

我的申请:

public class MyApplication extends Application {

private ApplicationComponent mApplicationComponent;

@Override
public void onCreate() {
    super.onCreate();
    initializeApplicationComponent();
}

private void initializeApplicationComponent() {
    mApplicationComponent = DaggerApplicationComponent
            .builder()
            .applicationModule(new ApplicationModule(this, Constant.BASE_URL))   // I think here needs to do something to use different URLs
            .build();
}

public ApplicationComponent getApplicationComponent() {
    return mApplicationComponent;
}

@Override
public void onTerminate() {
    super.onTerminate();
}
}

这就是我解决片段中的依赖关系的方式。

    protected void resolveDependency() {
    DaggerSerialComponent.builder()
            .applicationComponent(getApplicationComponent())
            .contactModule(new ContactModule(this))
            .build().inject(this);
}

问题是我需要在 Fragment 中使用 2 个 API 进行注入,才能从这些 API 中获取数据。

更新: 我已经创建了注释:

@Qualifier
@Retention(RUNTIME)
public @interface FirstApi{}

@Qualifier
@Retention(RUNTIME)
public @interface SecondApi{}

我的联系模块:

@Module
public class ContactModule {

private ContactView mContactView;

public ContactModule(ContactView contactView) {
    mContactView = contactView;

}

@PerActivity
@Provides
FirstContactService provideFirstContactService(@FirstApi Retrofit retrofit) {
    return retrofit.create(FirstContactService.class);
}

@PerActivity
@Provides
SecondContactService provideSecondContactService(@SecondApi Retrofit retrofit) {
    return retrofit.create(SecondContactService.class);
}

@PerActivity
@Provides
ContactView provideContactView() {
    return mContactView;
}
}

我总是收到错误“retrofit2.retrofit 不能在没有 @Provides 或 @Produces-annotated 方法的情况下提供”

应用组件

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {

    Retrofit exposeRetrofit();

    Context exposeContext();
}

【问题讨论】:

  • 您的改造是在哪里注入的?片段中应该有一个注入的改造实例,你可能也可以命名它

标签: android retrofit mvp dagger-2


【解决方案1】:

您只需将@Inject 注释与@Named() 注释一起使用,如下所示:

@Inject @Named("provideRetrofit") Retrofit mRetrofit;
@Inject @Named("provideRetrofit2") Retrofit mRetrofit2;

或者你甚至可以直接注入改造服务:

@Provides @Singleton
public CustomService provideCustomService(@Named("provideRetrofit") Retrofit retrofit) {
    return retrofit.create(CustomService.class);
}

【讨论】:

  • 当我将命名注释添加到 rertofit 时,我收到一个错误“retrofit2.Retrofit 不能在没有 @Inject 构造函数或提供注释的方法的情况下提供。retrofit2.Retrofit 在 com.myapp 提供。 dependencies.component.ApplicationComponent.exposeRetrofit()"
  • @STK90 您是否尝试过清理和重建您的项目?在 Dagger 生成你的对象图之前,依赖关系不会更新,直到执行新的构建才会发生。
【解决方案2】:

为您提供的改造实例添加@Named 注释,如下所示:

@Named("retrofit_one")
Retrofit provideRetrofit(@Named("ok-1") OkHttpClient client, GsonConverterFactory converterFactory, RxJavaCallAdapterFactory adapterFactory) {
return new Retrofit.Builder()
.baseUrl(FIRST_API_URL) 
.addConverterFactory(converterFactory) 
.addCallAdapterFactory(adapterFactory) 
.client(client) 
.build();
 }



@Named("retrofit_two")
    Retrofit provideRetrofit(@Named("ok-1") OkHttpClient client, GsonConverterFactory converterFactory, RxJavaCallAdapterFactory adapterFactory) {
    return new Retrofit.Builder()
    .baseUrl(SECOND_API_URL) 
    .addConverterFactory(converterFactory) 
    .addCallAdapterFactory(adapterFactory) 
    .client(client) 
    .build();
     }

然后在需要的地方注入两个实例,例如:

@Inject @Named("retrofit_one") Retrofit mRetrofitOne;   
@Inject @Named("retrofit_two") Retrofit mRetrofitTwo;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 2019-06-01
    相关资源
    最近更新 更多