【问题标题】:Kotlin, Dagger2, MVVM and ContributesAndroidInjectorKotlin、Dagger2、MVVM 和 ContributesAndroidInjector
【发布时间】:2019-10-17 13:57:26
【问题描述】:

我们在使用 Dagger2 时遇到问题,在编译时无法识别使用 ContributesAndroidInjector 指定的模块。

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

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

这是我们的模块,它会导致以下错误:

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

如果我们将声明提升到类级别,一切都会按预期运行:

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

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

请注意,此问题并非 FeatureViewModelModule 独有。如果放在@ContributesAndroidInjector 中,任何提供某种依赖的模块都将无法工作。

有趣的是,GitHub 上有一个project 似乎在做同样的事情而没有任何问题。我可以看到项目之间的唯一区别是我们的项目使用 Kotlin,而他们的项目使用 Java。

一些进一步的信息:

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
}

有人知道会发生什么吗?

【问题讨论】:

  • 我不认为ViewModelFactory 应该是@Singleton,但请take a look here 并用缺少的信息更新您的问题(what 无法提供哪里)如果问题仍然存在

标签: java android mvvm kotlin dagger-2


【解决方案1】:

@contributionAndroidInject请删除摘要

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

【讨论】:

    【解决方案2】:

    使用特定于 Dagger 的 baseApplication。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-24
      • 2017-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-14
      • 2018-07-11
      相关资源
      最近更新 更多