#android #dagger-2
#Android #dagger-2
Вопрос:
У меня есть класс с именем, AlertManager
для Activity
которого требуется, чтобы экземпляр отображал Toast
и AlertDialog
.
class AlertManager @Inject constructor(private val activity: Activity) {
fun showToast(message: String) {
Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
}
}
Теперь я хочу AlertManager
использовать зависимость в двух действиях HomeActivity
amp; ProductsActivity
. В настоящее время я создал модули для каждого Activity
подобного:
@Module
class HomeActivityModule {
@Provides
@ActivityContext
fun provideAlertManager(activity: HomeActivity) = AlertManager(activity)
}
И
@Module
class ProductsActivityModule {
@Provides
@ActivityContext
fun provideAlertManager(activity: ProductsActivity) = AlertManager(activity)
}
И привязать их к Dagger, как
@Module
abstract class ActivityProvider {
@ContributesAndroidInjector(modules = [HomeActivityModule::class])
@ActivityContext
abstract fun bindHomeActivity(): HomeActivity
@ContributesAndroidInjector(modules = [ProductsActivityModule::class])
@ActivityContext
abstract fun bindProductsActivity(): ProductsActivity
}
Теперь мои вопросы:
1) Как я могу избежать создания модулей для каждого activities и иметь общие, ActivityModule
которые я могу связать с чем Activity
угодно?
2) Допустим, у меня есть фрагмент с именем HomeFragment
inside HomeActivity
, тогда как я могу внедрить тот же AlertManager
экземпляр HomeActivity
внутри фрагмента?
Я застрял здесь довольно долго и пытался многое найти в Интернете, но я не могу найти какой-либо блог или руководство, которые могут помочь мне достичь того, что я ищу. Если кто-то может указать мне правильное направление, я буду благодарен.
Комментарии:
1. На GitHub есть связанная с этим проблема
Ответ №1:
1) Как я могу избежать создания модулей для каждого activities и иметь общий ActivityModule, который я могу связать с любым Activity, который я хочу?
У вас может быть какой-то AlertManagerModule, в который вы добавляете общую активность.
@Provides
fun provideAlertManager(activity: Activity) = AlertManager(activity)
Вам все равно придется создавать отдельные модули activity. Одно изменение, которое вы можете внести, это:
@Module
abstract class HomeActivityModule {
@Binds
abstract fun providesActivity(activity: HomeActivity) : Activity
}
А затем вы можете добавить их в класс ActivityProvider:
@Module
abstract class ActivityProvider {
@ContributesAndroidInjector(modules = [HomeActivityModule::class, AlertManagerModule::class])
abstract fun bindHomeActivity(): HomeActivity
@ContributesAndroidInjector(modules = [ProductsActivityModule::class, AlertManagerModule::class])
abstract fun bindProductsActivity(): ProductsActivity
}
2) Допустим, у меня есть фрагмент с именем HomeFragment внутри HomeActivity, тогда как я могу внедрить тот же экземпляр AlertManager HomeActivity внутри фрагмента?
Поскольку вы используете DaggerActivity и, скорее всего, используете DaggerFragment, фрагмент, созданный в HomeFragment, может напрямую получать AlertManager, просто используя аннотацию @Inject во фрагменте, который вы добавили в HomeActivityModule:
@Module
abstract class HomeActivityModule {
@Binds
abstract fun providesActivity(activity: HomeActivity) : Activity
@FragmentScope
@ContributesAndroidInjector
abstract fun providesHomeFragment() : HomeFragment;
}
Комментарии:
1. Ваше первое решение сработало, и я могу привязать экземпляр таким образом. Все еще необходимо создавать отдельные модули, но предложенный вами способ намного лучше. Однако я не могу внедрить
AlertManager
во фрагмент. Я все еще получаю:android.app.Activity cannot be provided without an @Inject constructor or an @Provides-annotated method
.2. @SandipSoni Вместо того, чтобы устанавливать
@ContributesAndroidInjector HomeFragment
непосредственно в свой AppComponent, установите его в тот же массив модулей, что и[HomeActivityModule::class, AlertManagerModule::class]
. Это означает, что ваш подкомпонентHomeFragment
находится под подкомпонентомHomeActivity
. Также убедитесь, что вашHomeActivity
расширяетсяDaggerActivity
.3. @SandipSoni Я вижу, в чем проблема. Вы должны добавить HomeFragment ContributesAndroidInjector не в отдельный appmodule, а внутри HomeActivityModule.
4. Спасибо, ребята, это наконец сработало. Я недоволен той частью, где мне все еще приходится создавать module для каждого activity, но, похоже, на данный момент это единственный способ и, следовательно, принятие этого ответа. Еще раз спасибо 🙂