Вам нужно будет переместить 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)
в onCreate
создает новый экземпляр этого подкомпонента и использует его для внедрения экземпляра Activity.
Ваш @CustomScope
(который может быть лучше назван здесь как @ActivityScope
) в методе @Provides PublishSubject<Boolean>
означает, что ваш экземпляр будет использовать тот же жизненный цикл, что и компонент, также аннотированный этой аннотацией области. Здесь это каждый автоматически сгенерированный подкомпонент. Кроме того, поскольку ваш модуль является неабстрактным классом с открытым конструктором no-arg , Dagger будет автоматически создавать новый экземпляр каждый раз, когда создает компонент, для которого требуется ваш модуль, что означает различный bus
для каждый экземпляр деятельности. (Это не может и не будет делать это для модулей, которые являются абстрактными классами или интерфейсами.)
Вы хотите, чтобы ваш объект bus
был одним и тем же экземпляром между операциями, что означает, что @CustomScope
/ @ActivityScope
слишком короток: вы хотите, чтобы объект пережил жизненный цикл любой отдельной деятельности. Это означает, что вам нужно либо сохранить экземпляр в другом месте и передать его в каждое действие, либо вам необходимо сохранить экземпляр в самом компоненте приложения. Я бы порекомендовал последнее, потому что это одна из проблем, которые Dagger был создан для решения, и потому что это автоматически сделает шину доступной для вашего приложения: подкомпоненты Dagger наследуют доступ ко всем привязкам в своих родительских компонентах. Это дает код, который вы видите выше. (Обратите внимание, что, выполнив это, вы сохраните экземпляр PublishSubject даже тогда, когда не будет отображаться действие, когда ваше приложение работает в фоновом режиме; если вам нужен один и тот же экземпляр между действиями, это является необходимым следствием, но выберите осторожно, чтобы не использовать слишком много фоновой памяти.)
Одной из альтернатив является то, что вы сами отслеживаете экземпляр bus
и вставляете его в каждое действие. Вы могли бы сделать это, если бы ваш модуль принял параметр, но , что довольно сложно сделать с dagger.android (который поддерживает @ContributesAndroidInjector
). Вы также можете написать метод @Provides
, который делегирует WeakReference, или использовать метод @Singleton
, описанный выше, чтобы написать держатель, который временно сохраняет ваш bus
между действиями. Тем не менее, поскольку Android в значительной степени контролирует ваши переходы между операциями и жизненным циклом активности, возможно, вы можете сохранить область действия bus
в @Singleton
, как я делал в приведенном выше коде.