0

一个对象如果注入到相同自定义范围下的 2 个子组件中,则每次创建该对象的新实例时。我希望将相同的实例传递给所有子组件

这是模块

@CustomScope
@Module
public class EventBusModule {

    PublishSubject<Boolean> bus = PublishSubject.create();

    @CustomScope
    @Provides
    public PublishSubject<Boolean> provideRxBus() {
        return bus;
    }
}

这些是我的子组件

@Module
public abstract class ActivityBindingModule {

    @CustomScope
    @ContributesAndroidInjector(modules = {HomeActivityModule.class, 
    EwayBillFragmentProvider.class, EventBusModule.class})
    abstract HomeActivity mainActivity();

    @CustomScope
    @ContributesAndroidInjector(modules = 
    {EwayBillDetailActivityModule.class, EventBusModule.class})
    abstract EwayBillDetailActivity ewayBillDetailActivity();
}

这些子组件写在 ActivityBindingModule 中,它被添加到我的应用程序组件中。现在我想要两个子组件中的 PublishSubject 对象的相同实例,我对匕首相当陌生,我想知道我做错了什么?

4

1 回答 1

1

您需要将您的移动bus到应用程序范围,这通常意味着使用注释@Singleton(如果这是您对安装 ActivityBindingModule 的顶级组件进行注释的方式)。您还需要将您的方法移动到安装在该组件上的模块中,这也可能是 ActivityBindingModule。

@Module
public abstract class ActivityBindingModule {

  @Singleton
  @Provides
  public PublishSubject<Boolean> provideRxBus() {
    // Dagger stores the instance in your Application component, so you don't have to.
    return PublishSubject.create();
  }

  /* ... your @ContributesAndroidInjector Activity bindings remain here ... */
}

首先,对您所看到的内容进行解释: @ContributesAndroidInjector为它注释的每个对象创建一个子组件,用您在@ContributesAndroidInjector方法和注释上放置的范围注释和模块进行标记,以便您调用AndroidInjection.inject(this)inonCreate创建该子组件的新实例并将其用于注入 Activity 实例。

方法上的@CustomScope(可能更好地命名为@ActivityScope此处)@Provides PublishSubject<Boolean>意味着您的实例将与也使用该范围注释注释的组件共享相同的生命周期。在这里,这是每个自动生成的子组件。此外,由于您的 Module 是具有公共无参数构造函数的非抽象类,因此 Dagger 将在每次创建需要您的模块的 Component 时自动创建一个新实例,这意味着bus每个 Activity 实例都不同。(对于抽象类或接口的模块,它不能也不会这样做。)


您希望您的bus对象在活动之间是相同的实例,这意味着@CustomScope/@ActivityScope太短了:您希望对象比任何单个 Activity 的生命周期都长。这意味着您需要将实例存储在其他位置并将其传递给每个 Activity,或者您需要将实例存储在您的应用程序组件本身中。我推荐后者,因为这是创建 Dagger 要解决的问题之一,并且因为这将自动使总线在您的应用程序中可用:Dagger 子组件继承对其父组件中所有绑定的访问。这给出了您在上面看到的代码。(请注意,通过这样做,即使没有 Activity 显示,当您的应用程序在后台运行时,您也会保留 PublishSubject 的实例;如果您希望在 Activity 之间使用相同的实例,这是必要的结果,

一种替代方法是您自己跟踪bus实例,并将其插入到每个活动中。你可以通过让你的 Module 接受一个参数来做到这一点,但这对于 dagger.android(其中 powers @ContributesAndroidInjector)是相当棘手的。您还可以编写一个@Provides委托给 WeakReference 的方法,或者使用@Singleton上面的技术编写一个临时存储您的bus活动之间的持有者。但是,由于 Android 对您在活动和活动生命周期之间的转换保持大量控制,因此最好像我在上面的代码中所做的那样保持范围内bus@Singleton

于 2018-09-11T18:39:31.653 回答