Dagger/MissingBinding java.util.Map,Provider> cannot be provided without an @Provides-annotated method

前端 未结 3 1683
盖世英雄少女心
盖世英雄少女心 2020-12-04 02:31

This is how I\'m trying to provide my ViewModelFactory:

@Suppress(\"UNCHECKED_CAST\")
@Singleton
class ViewModelFactory @Inject constructor(
            


        
3条回答
  •  隐瞒了意图╮
    2020-12-04 03:11

    First of all ViewModelFactory shouldn't be a Singleton. Anyway to fix this you should have:

    • a ViewModelFactory

      class ViewModelFactory @Inject constructor( private val creators: Map, @JvmSuppressWildcards Provider> ) : ViewModelProvider.Factory { override fun create(modelClass: Class): 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) } } }

    • bind this factory in your module class

      @Binds abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory

    • have a ViewModelKey

      @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.FUNCTION) @MapKey annotation class ViewModelKey(val value: KClass)

    • bind your viewModel in the desired module

      @Binds @IntoMap @ViewModelKey(MyViewModel::class) abstract fun bindCustomViewModel(viewModel: MyViewModel): ViewModel

    • then implement and use your viewModel

      @Inject lateinit var viewModelFactory: ViewModelFactory

      private val viewModel: MyViewModel by viewModels { viewModelFactory }

    This solution is tested with Kotlin 1.3.72 and latest version of Dagger2. Also please check at https://github.com/android/architecture-components-samples/tree/master/GithubBrowserSample

    Hope this will help you.

提交回复
热议问题