简体   繁体   中英

Kotlin, Dagger2, MVVM and ContributesAndroidInjector

We are having an issue with Dagger2 where modules specified using ContributesAndroidInjector are not being recognized at compile time.

// This doesn't work
@Module
abstract class ActivityBuildersModule {

    @ContributesAndroidInjector(
            modules = [
                FragmentBuildersModule::class,
                FeatureViewModelModule::class,
            ]
    )
    abstract fun contributeMainActivity(): MainActivity
}

This is our module and it results in the following error:

javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.

If we bring up the declaration up to the class level everything runs as expected:

// This works
@Module(includes = [
    FeatureViewModelModule::class,
])
abstract class ActivityBuildersModule {

    @ContributesAndroidInjector(
            modules = [
                FragmentBuildersModule::class,
            ]
    )
    abstract fun contributeMainActivity(): MainActivity
}

Note this issue is not exclusive to the FeatureViewModelModule. Any module that provides some kind of dependency will fail to work if put inside a @ContributesAndroidInjector.

What's interesting still, is there is a project on GitHub that seems to be doing the same thing without any problems. The only difference I can see between the projects is that ours is in Kotlin and theirs is in Java.

Some further information:

class MyApplication : DaggerApplication(){

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder().application(this).build()
    }
}
@Singleton
@Component(
        modules = [
            AndroidInjectionModule::class,
            ActivityBuildersModule::class,
            AppModule::class]
)
interface AppComponent : AndroidInjector<MyApplication> {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }
}
@Singleton
class ViewModelFactory @Inject constructor(
    private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        val creator = creators[modelClass] ?: creators.entries.firstOrNull {
            modelClass.isAssignableFrom(it.key)
        }?.value ?: throw IllegalArgumentException("unknown model class $modelClass")
        try {
            @Suppress("UNCHECKED_CAST")
            return creator.get() as T
        } catch (e: Exception) {
            throw RuntimeException(e)
        }

    }
}
@Suppress("unused")
@Module
abstract class FeatureViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(FeatureViewModel::class)
    abstract fun bindCompanyViewModel(featureViewModel: FeatureViewModel): ViewModel
}

Does anyone have any idea what might be going on?

for the @contributionAndroidInject please remove the abstract

@Module
interface ActivityBuilderModule {@ContributesAndroidInjector fun contributeAuthActivity(): MainActivity}

using the baseApplication specific to Dagger.

class BaseApplication : DaggerApplication() {
    override fun applicationInjector(): AndroidInjector<out DaggerApplication> 
    { 
        return DaggerAppComponent.builder().application(this).build()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM