繁体   English   中英

每次创建该对象的新实例时,如果将一个对象注入到同一自定义范围的2个子组件中

[英]one object if injected into 2 subcomponents under same custom scope, every time new instance is created of that object

每次为该对象创建新实例时,将一个对象注入到同一自定义范围内的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对象都具有相同的实例,我对dagger还是很陌生,我想知道我在做错什么吗?

您需要将bus移到Application范围内,这通常意味着使用@Singleton对其进行注释(如果这是对安装了ActivityBindingModule的顶级组件进行注释的方式)。 您还需要将方法移动到安装在该组件上的Module中,该模块也可能是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方法和注释上放置的模块进行标记,以便您在onCreate调用AndroidInjection.inject(this)创建该子组件的新实例,并使用它注入Activity实例。

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


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

一种替代方法是您自己跟踪bus实例,然后将其插入每个Activity中。 您可以通过让Module带有一个参数来完成此操作,但是使用dagger.android (为@ContributesAndroidInjector则非常棘手 您还可以编写一个委托给WeakReference的@Provides方法,或使用上面的@Singleton技术编写一个可在Activity之间临时存储您的bus的支架。 但是,由于Android可以很好地控制“活动”和“活动”生命周期之间的转换,因此最好像我在上面的代码中那样将bus保持在@Singleton范围内。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM