我不确定Dagger2的@Bind annotation.的目的
根据我在网上阅读的内容,我仍然不清楚,但这是一个示例:
@Module
public abstract class HomeModule {
@Binds
public abstract HomePresenter bindHomePresenter(HomePresenterImp
homePresenterImp);
}
和类定义如下:
public interface HomePresenter {
Observable<List<User>> loadUsers();
}
public class HomePresenterImp implements HomePresenter {
public HomePresenterImp(){
}
@Override
public Observable<List<User>> loadUsers(){
//Return user list observable
}
}
如果我只能使用提供注释,为什么我需要使用@Binds:
@Provides
public HomePresenter provideHomePresenter() {
return new HomePresenterImp();
}
@Binds而不是@Provides的用例是什么?如果我使用@Binds,我是否仍需要在我的appcomponent中声明它(当我使用@Binds时,它是一个抽象类)?
答案 0 :(得分:5)
@Binds可以完全等同于@Provides注释的方法,如下所示:
@Provides
public HomePresenter provideHomePresenter() {
return new HomePresenterImp();
}
...尽管您可能更喜欢使用HomePresenterImp作为方法参数的变体,该变体允许Dagger实例化HomePresenterImp(假设它具有@Inject构造函数),包括传递所需的任何依赖项。您也可以创建此static
,因此Dagger无需实例化Module实例即可调用它。
@Provides
public static HomePresenter provideHomePresenter(HomePresenterImp presenter) {
return presenter;
}
那为什么要选择@Binds
呢? Dagger has a FAQ about it,但归结为以下原因:
static
也可以完成此操作,但是如果您忘记了static
,您的@Provides方法仍将编译。 @Binds方法不会。Provider<HomePresenterImp>
强制转换为Provider<HomePresenter>
,并且只保留一个,而不是为HomePresenter保留一个,而只为HomePresenterImp调用一个。因此,整个事情可以很好地表示为:
@Binds abstract HomePresenter bindHomePresenter(HomePresenterImp presenter);
答案 1 :(得分:2)
在一个具体的情况下,您需要Bind
注释,假设您有一个BaseActivityModule
,它包含在提供活动视图模型的所有活动模块中。
@Module
object BaseActivityModule {
@Provides
@ActivityScope
@ActivityContext
@JvmStatic
fun provideViewModelProvider(
activity: AppCompatActivity,
viewModelFactory: ViewModelProvider.Factory
): ViewModelProvider = ViewModelProviders.of(activity, viewModelFactory)
}
在这里您看到我们需要提供一个AppCompatActivity
和一个ViewModelProvider.Factory
。由于活动是由android创建的,因此无法为AppCompatActivity
提供Provide
注释。
我们假设您的具体ActivityModule
例如MainActivityModule
将提供MainActivity
类,因为您创建了MainActivity子组件,或者您使用了ContributesAndroidInjector
自动创建了子组件(但这是另一回事)。
因此,我们有MainActivityModule
提供了MainActivity
,而我们的MainActivityModule
包括了BaseActivityModule
,需要一个AppCompatActivity
。因此,在这里Bind
的魔力,让我们告诉Dagger,当您需要AppCompatActivity
时,可以使用我们的MainActivity
。
@Module(includes = [BaseActivityModule::class])
abstract class MainActivityModule {
@Binds
@ActivityScope
abstract fun bindActivity(activity: MainActivity): AppCompatActivity
}
您可以从我的项目模板here
中看到更多内容