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

前端 未结 3 1615
盖世英雄少女心
盖世英雄少女心 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:01

    I faced the same issue recently. Version Kotlin:1.3.40 Dagger:2.23.2 I tried following the solutions mentioned in this post and here

    but none seemed to work. The annotation processor of Dagger is not playing well with KAPT and for the same reason, the builds are failing. This is also updated on Kotlin issue too.

    For me, converting both the ViewModelKey and ViewModelFactory to java worked. For Dagger, the tracking issue can be found here.

    Update Adding @JvmSuppressWildcards fixed the issue. Code looks like this:

    private val providers: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
    
    0 讨论(0)
  • 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<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) } } }

    • 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<out ViewModel>)

    • 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.

    0 讨论(0)
  • 2020-12-04 03:18

    After digging a little bit more I found the issue. It's completely un-related to the code I'm using. It regards Kotlin 1.3.30.

    Here some more information about it.

    Downgrading to Kotlin 1.3.21 resolved the problem.

    0 讨论(0)
提交回复
热议问题