[英]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.