Dagger 2 ContributesAndroidInjector proporciona actividad al module

Estoy tratando de encontrar una manera less rutinaria de implementar un ActivityModule que se usa en todas las actividades de mi aplicación. Esta es mi configuration actual:

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 (proporciona actividades para 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)) } } } } 

Lo que quiero que sea AppActivityModule en su lugar es:

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

Pero esto, bastante comprensible, me da un error /di/AppActivityModule_ContributeWelcomeActivityInjector.java:29: error: @Subcomponent.Builder is missing setters for requinetworking modules or subcomponents: [...di.modules.ActivityModule]

Mi pregunta es: ¿hay una manera less repetitiva de lograr lo que estoy tratando de hacer? Sé de @Bind y @BindsInstance (de esta respuesta ) pero parece que esto solo funciona si tengo un module por actividad y ato el tipo de actividad concreta que no quiero en este caso: quiero que ActivityModule funcione con todos ocupaciones.

Una forma de minimizar el text estándar es hacer un ActivityModule genérico y luego crear un pequeño Módulo específico por Actividad. Perdona mi falta de experiencia en Kotlin, pero aquí va:

 // 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 } } 

Y tu module:

 @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 } 

Tenga en count que aunque esto funciona para Activity, Service, BroadcastReceiver y otros, es posible que no desee ser tan rápido con Fragment. Esto se debe a que dagger.android maneja las jerarquías de fragments con los fragments principales, por lo que desde un componente secundario puede tener acceso a YourApplication, YourActivity, YourParentFragment y YourChildFragment, y a todos sus componentes. Si algo en YourChildFragmentComponent depende de un Fragment no calificado, sería ambiguo si realmente quiere YourParentFragment o YourChildFragment. Dicho esto, este layout tiene sentido para las Actividades y ciertos Fragmentos, por lo que tiene sentido usarlo (con precaución).

  • Enlace de datos de Kotlin y Android (BuildTools 2.0.0)
  • Kotlin crea una instancia de la list inmutable
  • Try-with-resources en Kotlin
  • Framework Azure Mobile App con Android (solo Kotlin)
  • Kotlin no selecciona los identificadores de resources
  • Android: el calendar especial de Java / Kotlin aparece
  • Recurso esperado de tipo ID
  • doAsync Kotlin-android no funciona bien
  • Mi propia solución para la ausencia de Try-with-Resources de Kotlin
  • Obteniendo un error al tratar con getter y setter en kotlin
  • Comstack el código de kotlin tanto para JVM como para JavaScript