简体   繁体   English

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

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

one object if injected into 2 subcomponents under same custom scope, every time new instance is created of that object. 每次为该对象创建新实例时,将一个对象注入到同一自定义范围内的2个子组件中。 I want same instance to be passed to all subcomponents 我希望将同一实例传递给所有子组件

this is the module 这是模块

@CustomScope
@Module
public class EventBusModule {

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

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

these are my subcomponents 这些是我的子组件

@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();
}

these subcomponents are written inside ActivityBindingModule which is added to my application component. 这些子组件写在ActivityBindingModule中,该组件已添加到我的应用程序组件中。 Now I want same instance of my PublishSubject object in both the subcomponents, I am fairly new to dagger and I want to know what am I doing wrong? 现在我想要两个子组件中的PublishSubject对象都具有相同的实例,我对dagger还是很陌生,我想知道我在做错什么吗?

You'll need to move your bus into Application scope, which typically means annotating it with @Singleton (if that's how you've annotated your top-level component that ActivityBindingModule is installed into). 您需要将bus移到Application范围内,这通常意味着使用@Singleton对其进行注释(如果这是对安装了ActivityBindingModule的顶级组件进行注释的方式)。 You'll also need to move your method into a Module installed on that component, which might as well be 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 ... */
}

First, an explanation of what you see: @ContributesAndroidInjector creates a subcomponent for each object it annotates, marked with the scope annotations and modules you put on the @ContributesAndroidInjector method and annotation, so that your call to AndroidInjection.inject(this) in onCreate creates a new instance of that subcomponent and uses it to inject the Activity instance. 首先,对所看到的内容进行解释: @ContributesAndroidInjector为每个其注释的对象创建一个子组件,并用作用域注释和您在@ContributesAndroidInjector方法和注释上放置的模块进行标记,以便您在onCreate调用AndroidInjection.inject(this)创建该子组件的新实例,并使用它注入Activity实例。

Your @CustomScope (which may be better-named as @ActivityScope here) on the @Provides PublishSubject<Boolean> method means that your instance will share the same lifecycle as the component that is also annotated with that scope annotation. @CustomScope (可能被命名为更好为@ActivityScope这里)在@Provides PublishSubject<Boolean>方法意味着您的实例将共享相同的生命周期为还标注了该范围注释的组件。 Here, that's each automatically-generated subcomponent. 在这里,这是每个自动生成的子组件。 Furthermore, because your Module is a non-abstract class with public no-arg constructor , Dagger will automatically create a new instance every time it creates a Component that requires your module, which means a different bus for each Activity instance. 此外,由于您的模块是具有公共no-arg构造函数非抽象类 ,因此Dagger每次创建需要您模块的Component时都会自动创建一个新实例,这意味着每个Activity实例都有不同的bus (It can't and won't do so for Modules that are abstract classes or interfaces.) (对于抽象类或接口的模块,它不能也不会这样做。)


You want your bus object to be the same instance between Activities, which means that @CustomScope / @ActivityScope is much too short: You want the object to outlast any single Activity's lifecycle. 您希望bus对象在Activity之间是相同的实例,这意味着@CustomScope / @ActivityScope太短了:您希望对象比任何单个Activity的生命周期都要长。 This means that you'll either need to store the instance elsewhere and pass it into each Activity, or you'll need to store the instance in your Application component itself. 这意味着您要么需要将实例存储在其他位置,然后将其传递给每个Activity,要么需要将实例存储在Application组件本身中。 I'd recommend the latter, because this is one of the problems Dagger was created to solve, and because this will automatically make the bus available across your application: Dagger subcomponents inherit access to all of the bindings in their parent components. 我建议使用后者,因为这是Dagger创建的要解决的问题之一,并且因为这将自动使总线在整个应用程序中可用:Dagger子组件继承了对其父组件中所有绑定的访问。 That gives the code you see above. 这给出了您在上面看到的代码。 (Note that by doing this, you'll keep the instance of PublishSubject around even when there is no Activity showing, when your application is running in the background; if you want the same instance between Activities, this is a necessary consequence, but choose this carefully to avoid too much background memory use.) (请注意,这样做时,即使没有活动显示,当应用程序在后台运行时,您也将保留PublishSubject的实例;如果您希望在Activity之间使用相同的实例,则这是必然的结果,但是请选择请谨慎操作,以免过多使用背景内存。)

One alternative is that you keep track of the bus instance yourself, and insert it into each Activity. 一种替代方法是您自己跟踪bus实例,然后将其插入每个Activity中。 You could do this by having your Module take a parameter, but that is rather tricky to do with dagger.android (which powers @ContributesAndroidInjector ). 您可以通过让Module带有一个参数来完成此操作,但是使用dagger.android (为@ContributesAndroidInjector则非常棘手 You could also write a @Provides method that delegates to a WeakReference, or use the @Singleton technique above to write a holder that temporarily stores your bus between Activities. 您还可以编写一个委托给WeakReference的@Provides方法,或使用上面的@Singleton技术编写一个可在Activity之间临时存储您的bus的支架。 However, because Android keeps a lot of control over your transitions between Activities and the Activity lifecycle, it may be the best you can do to keep the bus in @Singleton scope as I did in the code above. 但是,由于Android可以很好地控制“活动”和“活动”生命周期之间的转换,因此最好像我在上面的代码中那样将bus保持在@Singleton范围内。

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

相关问题 每次创建新对象 - new object created every time 匕首刀柄注入 object 在自定义视图中为 null - Dagger hilt injected object is null in custom view 片段onCreateView被多次调用,以便每次都创建片段的新实例 - Fragment onCreateView getting called multiple time so that new instance of fragment is created every time 为收到的每个广播创建一个MyAppWidgetProvider的新实例吗? - A new instance of MyAppWidgetProvider created for every broadcast received? 每次单击按钮时,Firebase 都会创建一个新对象 - Firebase create a new object every time I click a button 是否每次启动活动都会创建该类的新对象? - Is each time and activity starts a new object of that class created? Dagger2如何使注入的对象知道是谁创建的 - Dagger2 How to make Injected Object know who created it 将一个自定义视图的对象访问到另一个在Activty类上创建的Customview - Access object of one custom view to another Customview, created on Activty class Dagger 2范围和子组件 - Dagger 2 scope and subcomponents 每次按下按钮时都会创建新活动 - New Activity created every time Button is pressed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM