Я новичок ie в Dagger. Я использовал этот ответ , чтобы изменить URL во время выполнения.
Также я использовал три модуля и три компонента, как показано ниже :
примечание: у меня есть буксирные компоненты (ApplicationComponent,ActivityComponent
) и один субкомпонент (UrlComponent
). В дополнение я использую @Singletone
, @PerUrl
и @PerActivty
в качестве области видимости.
Когда я хочу Inject
RestApi
в каждом действии, я сталкиваюсь с этой ошибкой:
error: com.example.testdagger2.RestApi cannot be provided without an @Provides- or @Produces-annotated method.
com.example.dagger2.RestApi is injected at
com.example.dagger2.RestApiHelper.restApi
com.example.dagger2.RestApiHelper is injected at
com.example.dagger2.MainActivity.restApiHelper
com.example.testdagger2.MainActivity is injected at
com.example.testdagger2.di.component.ActivityComponent.inject(mainActivity)
Прежде чем мне пришлось изменить URL-адрес в среде выполнения, у меня было два компонента и модули (appCompoent и activtyComponent), и все провайдеры (такие как Retrofit и RestApi, ...) были в ApplicationModule, и программа работала нормально.
ApplicationComponent. java
@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(ExampleApplication exampleApplication);
@ApplicationContext
Context context();
Application application();
UrlComponent plus(UrlModule component);
}
ApplicationModule. java
@Module
public class ApplicationModule {
private Application mApplication;
public ApplicationModule(Application application) {
this.mApplication = application;
}
@Provides
@ApplicationContext
Context provideContext() {
return mApplication;
}
@Provides
Application provideApplication() {
return mApplication;
}
}
UrlComponent. java
@PerUrl
@Subcomponent(modules = UrlModule.class)
public interface UrlComponent {
}
UrlModule. java
@Module
public class UrlModule {
private String url;
public UrlModule(String url) {
this.url = url;
}
@Provides
@PerUrl
OkHttpClient provideOkhttpClient() {
return new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.build();
}
@Provides
@PerUrl
Retrofit provideRetrofit(String baseURL, OkHttpClient client) {
return new Retrofit.Builder()
.baseUrl(baseURL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
}
@Provides
RestApiHelper provideRestApiHelper(RestApiHelper restApiManager) {
return restApiManager;
}
@Provides
public RestApi provideApiService() {
return provideRetrofit(url, provideOkhttpClient())
.create(RestApi.class);
}
}
ActivityComponent. java
@PerActivity
@Component(modules = ActivityModule.class,dependencies = ApplicationComponent.class)
public interface ActivityComponent {
void inject(MainActivity mainActivity);
.
.
.
}
ActivityModule. java
@Module
public class ActivityModule {
private AppCompatActivity mActivity;
public ActivityModule(AppCompatActivity mActivity) {
this.mActivity = mActivity;
}
@Provides
@ActivityContext
Context provideContext() {
return mActivity;
}
@Provides
AppCompatActivity provideActivity() {
return mActivity;
}
.
.
.
}
RestApi. java
public interface RestApi {
Single<Object> getquestionlist(@Query("page") int page);
Single<Object> getCategoryList();
}
RestApiHelper. java
public class RestApiHelper implements RestApi {
@Inject
RestApi restApi;
@Inject
public RestApiHelper(RestApi restApi) {
this.restApi = restApi;
}
@Override
public Single<Object> getquestionlist(int page) {
return restApi.getquestionlist(1);
}
@Override
public Single<Object> getCategoryList() {
return restApi.getCategoryList();
}
Пример приложения. java
public class ExampleApplication extends Application {
@Inject
ApplicationComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(this)).build();
appComponent.inject(this);
appComponent.plus(new UrlModule("www/test/en"));
}
public ApplicationComponent getAppComponent() {
return appComponent;
}
}
BaseActivity. java
public class BaseActivity extends AppCompatActivity {
ActivityComponent activityComponent;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//activityComponent=DaggerActivityComponent.builder().applicationModule()
activityComponent= DaggerActivityComponent.builder()
.applicationComponent(((ExampleApplication)getApplication()).getAppComponent())
.build();
}
public ActivityComponent getActivityComponent() {
return activityComponent;
}
}
MainActivity.jaqva
public class MainActivity extends BaseActivity {
@Inject
RestApiHelper restApiHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityComponent component= getActivityComponent();
component.inject(this);
restApiHelper.getquestionlist(1).subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
}
});
Теперь у меня есть вопросы о буксировке:
1-дел. Не все провайдеры, встроенные в Urlmodule
, могут быть добавлены к ApplicationModule
(UrlModule is Subcomepoent of the ApplicationComponent
)
@PerActivity
@Component(modules = ActivityModule.class,dependencies = ApplicationComponent.class)
public interface ActivityComponent {
, и поскольку ApplicationComponent является зависимостями ActivityComponent, все эти Providers
можно использовать в Компонент Activity также?
2-И как базовый c вопрос, в чем проблема?