最近兩個月才剛開始在正式項目中使用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<>();
}
再次編譯代碼,成功!