我有一个Activity和它的演示者,都注入了一个适配器。 Activity需要在RecyclerView上设置适配器,并且演示者需要它在数据更改时调用更新方法(例如:notifyItemChanged
)。
问题是因为适配器被注入两次,所以演示者和活动不具有相同的实例。我需要Dagger只创建它的一个实例。但是,适配器需要Activity的上下文并且@ActivityScope
可以防止内存泄漏,这意味着我不能在其上使用@Singleton
范围。
有什么我不明白的吗?有没有办法在两个类中注入适配器,而无需在演示者或活动中使用setAdapter
方法手动设置它?或者有没有办法限制适配器创建的实例数量?
编辑:依赖注入文件:
@Module
public interface MainModule {
@ActivityContext @Binds
Context context(MainActivity activity);
@ActivityScope @Binds
MainContract.Presenter presenter(MainPresenter presenter);
// CHILD FRAGMENT
@FragmentScope @ContributesAndroidInjector
ChildFragment childFragment();
@ActivityScope @Binds
ChildContract.Presenter childPresenter(ChildPresenter presenter);
@ActivityScope @Binds
ChildContract.AdapterView adapterView(MyAdapter adapter);
}
ChildFragment
,ChildPresenter
和MyAdapter
类使用@ActivityScope
进行注释。
这是我使用它的唯一方法,对我来说似乎不对,因为ChildPresenter和MyAdapter仅用于片段。但是,使用@FragmentScope
注释它们会引发错误:"可能不会引用具有不同范围的绑定"。此外,片段"提供商"和片段本身用两个不同的范围注释?
答案 0 :(得分:2)
在 MVP 架构中,演示者应该只关心业务逻辑。这意味着演示者对Android内容一无所知,也不包含任何Android特定项目。
在您的情况下,您写道演示者拥有适配器并在其上调用HTML
<input type="text"
ng-model="data.ssnDisplay"
ng-blur="blurFunction()">
JAVASCRIPT
// on page load
if (newUser === true) {
$scope.data.ssn = ''
}
else {
// would normally be delivered via a service endpoint (hard coded here)
$scope.data.ssn = '123456789'
}
// create display-only property
$scope.data.ssnDisplay = $scope.data.ssn;
// on blur, update display-only property
$scope.blurFunction = function () {
$scope.data.ssnDisplay = 'XXXXX' + $scope.data.ssn.substring(5);
}
// always maintain primary ssn value - you'll need this when
// posting/saving your data back to your database
$scope.$watch("data.ssnDisplay", function () {
$scope.data.ssn = $scope.data.ssnDisplay;
})
方法。这是Android特定的项目,不应该这样。 视图是负责持有适配器的人,并且演示者与适配器的任何互动都应通过视图。
这对你的例子意味着什么:
notifyItemChanged
notifyAdapterItemChanged
(以及视图依次调用适配器)旁注:如果您需要提供相反的数据(从适配器到演示者),我建议在演示者中添加一个特殊的adapterInterface,您可以将其作为适配器中的weakReference保留。
如果您有任何其他问题,希望有帮助并告诉我......