我现在正在学习 Dagger 2,没有代码解释这个问题对我来说太痛苦了,所以让我先列出我所有的模块、组件等:
应用类
public class App extends Application {
private ApiComponent mApiComponent = null;
private AppComponent mAppComponent = null;
public ApiComponent getApiComponent() {
if (mApiComponent == null) {
// Dagger%COMPONENT_NAME%
mApiComponent = DaggerApiComponent.builder()
// list of modules that are part of this component need to be created here too
.appModule(new AppModule(this)) // This also corresponds to the name of your module: %component_name%Module
.apiModule(new ApiModule(this))
.build();
}
return mApiComponent;
}
public AppComponent getAppComponent() {
if (mAppComponent == null) {
// If a Dagger 2 component does not have any constructor arguments for any of its modules,
// then we can use .create() as a shortcut instead:
mAppComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
}
return mAppComponent;
}
}
应用组件
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(RetrofitDemo target);
}
应用模块
private final Application mContext;
AppModule(Application context) {
mContext = context;
}
@Singleton
@ForApplication
@Provides
Application provideApplication() {
return mContext;
}
@Singleton
@ForApplication
@Provides
Context provideContext() {
return mContext;
}
API组件
@Singleton
@Component(dependencies = {AppModule.class},modules = {ApiModule.class})
public interface ApiComponent {
void inject(RetrofitDemo target);
}
API模块
@Inject
Context application;
@Inject
public ApiModule(Context context){
this.application = context;
}
@Provides
@Singleton
Gson provideGson() {
return new GsonBuilder()
// All timestamps are returned in ISO 8601 format:
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
// Blank fields are included as null instead of being omitted.
.serializeNulls()
.create();
}
@Provides
@Singleton
OkHttpClient provideOkHttpClient() {
...
}
@Provides
@Singleton
public Retrofit provideRetrofit(Gson gson,OkHttpClient okHttpClient){
return new Retrofit.Builder()
.baseUrl(DribbleApi.END_POINT)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.build();
}
我的 Activity 将是这样的:
@Inject
Retrofit mRetrofit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_retrofit_demo);
((App) getApplication()).getApiComponent().inject(this);
...
这是错误信息:
Error:(18, 10) : retrofit2.Retrofit cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.
retrofit2.Retrofit is injected at com.sinyuk.yuk.RetrofitDemo.mRetrofit
com.sinyuk.yuk.RetrofitDemo is injected at com.sinyuk.yuk.AppComponent.inject(target)
让我困惑的是改造实例是由ApiModule提供的,但是为什么错误消息说它是在appComponent注入(inject)的?而且我在我的代码中找不到任何错误的地方。 T_T,学习 Dagger 对我来说太沉重了......我想。
此外,在我的例子中,我在 AppComponent 中写了 dependencies = AppModule.class module = ApiModule.class
,我认为这似乎是正确的,但是如果我写了 module = ( {AppComponent.class,ApiComponent.class})
,它也工作正常。任何人都可以解释我为什么?
请检查我的代码并给我一些建议。提前致谢!
最佳答案
@Sinyuk 这里有很多东西要拆开,乍一看 Dagger 有点复杂,但我想我可以提供帮助。首先,您对 @Component
注释有概念上的误解。 Component
是您定义的接口(interface),Dagger 通过代码生成实现该接口(interface)。您将定义接口(interface),并用 @Component
对其进行注释,然后您将提供一组 Module
给 Dagger 以在生成过程中使用。您使用的模块通过 @Component
注释的 modules
元素传入。如果你想让一个 Component
允许另一个 Component
支持注入(inject)过程,那么在注入(inject)时你需要让 Dagger 使用的任何 Component
接口(interface)您的代码将通过 @Component
注释的 dependencies
元素传入。
--
因此,以下是不正确的
@Component(dependencies = AppModule.class module = ApiModule.class`)
相反,要让一个组件使用两个模块,请编写:
@Component(modules = {ApiModule.class, AppModule.class})
或者,让一个组件使用一个模块并依赖于另一个组件
@Component(modules = {AppModule.class}, dependencies = {ApiComponent.class})
我希望这能帮助您走上正确的道路。如果您有任何后续问题,请告诉我。
关于android - 如果没有 @Inject 构造函数或来自 @Provides- 或 @Produces- 注释的方法,则不能提供改造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38058364/