最近两个月才刚开始在正式项目中使用Dagger2,在此记录一下遇到的坑
Dagger2无法注入Context
Moule 跟 Component 部分代码
@Module
public class ApplicationModule {
private final Application application;
public ApplicationModule(Application application) {
this.application = application;
}
@Provides
@Singleton
Application provideApplication() {
return application;
}
@Provides
@ApplicationContext
Context provideApplicationContext() {
return application;
}
@Provides
@Singleton
TeacherService provideStudentService() {
return ServiceFactory.makeStudentService();
}
@Provides
@Singleton
ActManager provideActManager() {
return new ActManager();
}
}
Module
@Module
public class ActivityModule {
private Activity activity;
public ActivityModule(Activity activity) {
this.activity = activity;
}
@Provides
public Activity provideActivity() {
return activity;
}
@Provides
@ActivityContext
public Context provideContext() {
return activity;
}
}
ActivityComponent
@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class)
public interface ActivityComponent {
void inject(AttendanceActivity attendanceActivity);
}
使用情景
我希望把一个 RecyclerView 的 Adapter 通过 @Inject 注解注入到 Activity 中,adapter 的构造方法中包含一个 Context 参数
adapter
private Context context;
@Inject
public AttendanceAdapter( Context context)
this.context = context;
}
错误信息
在 activity 中使用 @Inject 注入这个 adapter 之后运行代码报错
Error:(43, 10) 错误: android.content.Context cannot be provided without an @Provides-annotated method.
android.content.Context is injected at
com.zidian.teacher.ui.course.adapter.AttendanceAdapter.<init>(context)
com.zidian.teacher.ui.course.adapter.AttendanceAdapter is injected at
com.zidian.teacher.ui.course.activity.AttendanceActivity.adapter
com.zidian.teacher.ui.course.activity.AttendanceActivity is injected at
com.zidian.teacher.di.componet.ActivityComponent.inject(attendanceActivity)
解决方案
错误信息里面说我没有无法为 adapter 的构造方法提供 Context 参数, 仔细看了几遍代码: 明明在 ActivityModule 里提供了 Context 实例,后面再看 ApplicationModule 发现里面也有提供 Context 实例的方法。
原来是 Dagger2 遇到两个相同的参数,不知道到底该提供哪一个给我的 adapter 使用, 这个时候才想起 @Qualifier 注解, 这个限定词就是专门为解决若一个类的实例有多种方法可以创建出来, Component 不知道选择哪种方法来创建该类的实例, 这个时候就需要我们用 @Qualifier 注解创建不同的限定符 比如: ApplicationContext, ActivityContext 等
修改 Adapter 类的构造方法为:
@Inject
public AttendanceAdapter(@ActivityContext Context context) {
students = new ArrayList<>();
}
再次编译代码,成功!