多次注入范围对象的相同实例

时间:2018-05-28 21:30:54

标签: android android-adapter dagger-2 android-mvp

我有一个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);

}

ChildFragmentChildPresenterMyAdapter类使用@ActivityScope进行注释。

这是我使用它的唯一方法,对我来说似乎不对,因为ChildPresenter和MyAdapter仅用于片段。但是,使用@FragmentScope注释它们会引发错误:"可能不会引用具有不同范围的绑定"。此外,片段"提供商"和片段本身用两个不同的范围注释?

1 个答案:

答案 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保留。

如果您有任何其他问题,希望有帮助并告诉我......