Dagger 2 ContributesAndroidInjector обеспечивает активность модуля

Я пытаюсь понять, что менее-шаблонный способ реализовать ActivityModule который используется во всех моих приложениях. Это моя текущая настройка:

ActivityModule :

 @Module class ActivityModule(private val activity: Activity) { @Provides @ActivityScope fun providesActivity(): Activity = activity @Provides @ActivityContext @ActivityScope fun providesContext(): Context = activity @Provides @ActivityContext @ActivityScope fun providesLayoutInflater(): LayoutInflater = activity.layoutInflater @Provides @ActivityContext @ActivityScope fun providesResources(): Resources = activity.resources } 

AppActivityModule (предоставляет действия для AndroidInjectionModule)

 @Module(subcomponents = [ AppActivityModule.WelcomeActivityComponent::class ]) internal abstract class AppActivityModule { @Binds @IntoMap @ActivityKey(WelcomeActivity::class) abstract fun bindWelcomeActivityInjectorFactory(builder: WelcomeActivityComponent.Builder): AndroidInjector.Factory<out Activity> @ActivityScope @Subcomponent(modules = [(ActivityModule::class)]) interface WelcomeActivityComponent : AndroidInjector<WelcomeActivity> { @Subcomponent.Builder abstract class Builder : AndroidInjector.Builder<WelcomeActivity>() { abstract fun activityModule(myActivityModule: ActivityModule): AndroidInjector.Builder<WelcomeActivity> override fun seedInstance(instance: WelcomeActivity) { activityModule(ActivityModule(instance)) } } } } 

Вместо этого я хочу, чтобы AppActivityModule был следующим:

 @Module internal abstract class AppActivityModule { @ContributesAndroidInjector(modules = [(ActivityModule::class)]) abstract fun contributeWelcomeActivityInjector(): WelcomeActivity } 

Но это, совершенно понятно, дает мне ошибку /di/AppActivityModule_ContributeWelcomeActivityInjector.java:29: error: @Subcomponent.Builder is missing setters for required modules or subcomponents: [...di.modules.ActivityModule]

Мой вопрос: есть ли более способный способ достичь того, что я пытаюсь сделать? Я знаю о @Bind и @BindsInstance (из этого ответа ), но это, похоже, работает только в том случае, если у меня есть модуль для каждого действия и привязываю конкретный вид активности, который я не хочу в этом случае, – я хочу, чтобы ActivityModule работал со всеми виды деятельности.

Одним из способов минимизации шаблона является создание общего ActivityModule, а затем создание небольшого отдельного модуля для каждой операции. Простите мою неопытность Котлина, но здесь говорится:

 // 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's no reason to have Dagger save your Context instance in a Provider. @Binds @ActivityContext fun providesContext(activity: Activity): Context // This doesn't *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. 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 и других, вы можете не захотеть так быстро об этом для фрагмента. Это связано с тем, что dagger.android обрабатывает иерархии фрагментов с родительскими фрагментами, поэтому из дочернего компонента у вас может быть доступ к YourApplication, YourActivity, YourParentFragment и YourChildFragment и всем их компонентам. Если что-то в YourChildFragmentComponent зависит от неквалифицированного фрагмента, было бы двусмысленно, действительно ли он хочет YourParentFragment или YourChildFragment. Тем не менее, этот дизайн имеет смысл для Деяний и определенных фрагментов, поэтому имеет смысл использовать его (осторожно).

Intereting Posts
Kotlin: использование статических методов google-guava в качестве расширений Как получить номер мобильного телефона с SIM-карты в Android Программно с использованием языка kotlin? Поведение System.identityHashCode () для примитивов У Котлина есть синтаксис для картографических букв? Нечеткость разрешения перегрузки Котлина в стандартной библиотеке Кинжал 2, не может вводить презентатора в мою деятельность Kotlin: общий метод и цикл для запроса итератора () Как использовать ByteArray.getOrElse как загрузить файл в S3 Amazon от Okhttp3 и Android Копирование файла автоматически с помощью pom Почему этот способ случайного создания графика несправедлив? Есть ли способ построить HashSet с функцией инициализации в Котлин? В Kotlin, как вы изменяете содержимое списка во время итерации Определить возвращаемый тип Retrofit с использованием интерфейса вместо класса nullPointerException на вспомогательном классе sharedpreferences При запуске теста