【发布时间】:2020-05-20 12:42:58
【问题描述】:
我是 Dagger 的新手。我使用 this answer 在运行时更改 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();
}
ExampleApplication.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中内置的所有Provider都添加到ApplicationModule(UrlModule is Subcomepoent of the ApplicationComponent)
@PerActivity
@Component(modules = ActivityModule.class,dependencies = ApplicationComponent.class)
public interface ActivityComponent {
既然ApplicationComponent是一个ActivityComponent依赖,那么所有这些Providers也可以在ActivityComponent中使用吗?
2-作为一个基本问题,问题出在哪里?
【问题讨论】:
-
删除
RestApiHelper是多余的。只需使用RestApi。
标签: java android retrofit dagger-2 rx-android