Ответ 1
Один из способов минимизировать шаблон - создать общий модуль ActivityModule, а затем создать небольшой конкретный модуль для каждого действия. Прости мой неопытность Kotlin, но здесь идет:
// Abstract class so you don't have to provide an instance
@Module
abstract class ActivityModule {
// No need for ActivityScope: You're always binding to the same Activity, so
// there no reason to have Dagger save your Context instance in a Provider.
@Binds @ActivityContext
abstract fun providesContext(activity: Activity): Context
// This does not *have* to be in a companion object, but that way
// Android can do a static dispatch instead of a virtual method dispatch.
// If you don't need that, just skip the constructor arguments and make these
// normal methods and you'll be good to go.
@Module
companion object {
@JvmStatic @Provides @ActivityContext
fun providesLayoutInflater(activity: Activity): LayoutInflater =
activity.layoutInflater
@JvmStatic @Provides @ActivityContext
fun providesResources(activity: Activity): Resources = activity.resources
}
}
И ваш модуль:
@Module
internal abstract class AppActivityModule {
@Module
internal interface WelcomeActivityModule {
// The component that @ContributesAndroidInjector generates will bind
// your WelcomeActivity, but not your Activity. So just connect the two,
// and suddenly you'll have access via injections of Activity.
@Binds fun bindWelcomeActivity(activity: WelcomeActivity) : Activity
}
@ContributesAndroidInjector(
modules = [ActivityModule::class, WelcomeActivityModule::class])
abstract fun contributeWelcomeActivityInjector(): WelcomeActivity
}
Обратите внимание, что хотя это работает для Activity, Service, BroadcastReceiver и других, вы, возможно, не захотите быть настолько быстрыми для Fragment. Это связано с тем, что dagger.android обрабатывает иерархии фрагментов с родительскими фрагментами, поэтому из дочернего компонента вы можете получить доступ к YourApplication, YourActivity, YourParentFragment и YourChildFragment, а также ко всем их компонентам. Если что-то в YourChildFragmentComponent зависит от неквалифицированного фрагмента, было бы неоднозначно, действительно ли оно хочет YourParentFragment или YourChildFragment. Тем не менее, этот дизайн имеет смысл для действий и определенных фрагментов, поэтому имеет смысл использовать его (осторожно).
ОБНОВЛЕНИЕ: Что здесь делает @ActivityContext
?
@ActivityContext
здесь вы можете определить квалификационную аннотацию, которую вы можете использовать для различения привязок того же типа в Dagger и других DI-средах, предположительно @ApplicationContext Context
и @ActivityContext Context
. Было бы неплохо не попробовать его, но я настоятельно рекомендую сохранить его и избегать привязки неквалифицированного контекста: контексты приложения и действия могут отличаться, особенно в многоэкранных или автоматических средах, и для получения нужных ресурсов и данных, которые вы должен быть точным, о котором вы используете. Вы можете использовать этот в качестве примера.