2016-10-06 2 views
2

В моем проекте я использую Retrofit и пытаюсь использовать Кинжал для инъекций зависимостей. У меня также есть 2 услуги по обновлению с различными API. Мне нужно одновременно использовать два разных API с разными базовыми командами. Я застрял здесь и не знаю, что делать дальше.Dagger2, предоставляя экземпляры Retrofit с разными API-интерфейсами одновременно

Мой ApplicationModule:

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

Проблема заключается в том, что мне нужно сделать инъекцию 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 -направленный метод "

ПриложениеComponent

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

    Retrofit exposeRetrofit(); 

    Context exposeContext(); 
} 
+0

, где ваш Модифицированный вводят? В фрагменте должен быть инъецированный модифицированный экземпляр, и вы, вероятно, можете его назвать – njzk2

ответ

5

Вы просто использовать @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); 
} 
+0

Когда я добавляю аннотацию Named к rertofit, я получил сообщение об ошибке «retrofit2.Retrofit не может быть предоставлен без конструктора @Inject или из аннотированного метода Provides . retrofit2.Retrofit предоставляется по адресу com.myapp.dependencies.component.ApplicationComponent.exposeRetrofit() " – STK90

+0

@ STK90 Вы пытались очистить и перестроить свой проект? Зависимости не будут обновляться до тех пор, пока Dagger не создаст граф объектов, что не произойдет, пока не будет выполнена новая сборка. – Bryan