Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/191.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Dagger2缺少绑定无法提供ViewModel密钥_Android_Kotlin_Dependency Injection_Dagger 2_Android Viewmodel - Fatal编程技术网

Android Dagger2缺少绑定无法提供ViewModel密钥

Android Dagger2缺少绑定无法提供ViewModel密钥,android,kotlin,dependency-injection,dagger-2,android-viewmodel,Android,Kotlin,Dependency Injection,Dagger 2,Android Viewmodel,我正在尝试使用Dagger2和多绑定创建ViewModel的依赖项注入,但是我收到了这个错误,我无法使它工作,我尝试了下面的几个答案,但没有一个对我有帮助 这是我收到的错误: SaveMyHeroApplicationComponent.java:8: error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.

我正在尝试使用Dagger2和多绑定创建ViewModel的依赖项注入,但是我收到了这个错误,我无法使它工作,我尝试了下面的几个答案,但没有一个对我有帮助

这是我收到的错误:

SaveMyHeroApplicationComponent.java:8: error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.

我知道这个问题有几个问题,但我试了几个,没有一个对我有效

以下是我尝试阅读和检查的解决方案链接:

试着用一个例子

Dagger Android本身就是一个烂摊子,遵循一些模板不要走错方向很重要。也许您的方法也可以修复,但我建议您尝试更改您的模式:

自定义视图模型工厂应具有@Inject-in构造函数: 对于您的所有对-Activitiy/ViewModel和Fragment/ViewModel,您应该像这样添加模块,但您可以为所有对添加单个模块,这取决于您: 在Dagger组件中,您应该使用步骤3中的所有模块:
谢谢,我遵循了你的步骤+蓝图,我能够修复!
class SaveMyHeroApplication : DaggerApplication() {

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerSaveMyHeroApplicationComponent.factory().create(this)
    }
}

@Singleton
@Component(modules = [AndroidInjectionModule::class, MainActivityModule::class])
interface SaveMyHeroApplicationComponent : AndroidInjector<SaveMyHeroApplication> {

    @Component.Factory
    interface Factory {
        fun create(@BindsInstance context: Context): SaveMyHeroApplicationComponent
    }
}

@Module(includes = [NetworkModule::class, HomeModule::class])
class MainActivityModule {

    @Provides
    fun provideViewModelFactoryProviders(
        providers: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
    ): ViewModelProvider.Factory = SaveMyHeroViewModelFactory(providers)
}
class SaveMyHeroViewModelFactory(
    private val providers: Map<Class<out ViewModel>, Provider<ViewModel>>
) : ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T =
        requireNotNull(getProvider(modelClass).get()) {
            "Provider for $modelClass returned null"
        }


    private fun <T : ViewModel> getProvider(modelClass: Class<T>): Provider<T> =
        try {
            requireNotNull(providers[modelClass] as Provider<T>) {
                "No ViewModel provider is bound for class $modelClass"
            }
        } catch (error: ClassCastException) {
            error("Wrong provider type registered for ViewModel type $error")
        }
}


@Module(includes = [HomeModule.ProvideViewModel::class])
abstract class HomeModule {

    @ContributesAndroidInjector(modules = [InjectViewModel::class])
    abstract fun bind(): HomeFragment

    @Module
    class ProvideViewModel {

        @Provides
        @IntoMap
        @ViewModelKey(HomeViewModel::class)
        fun provideHomeViewModel() = HomeViewModel()
    }

    @Module
    class InjectViewModel {

        @Provides
        fun provideHomeViewModel(
            factory: ViewModelProvider.Factory,
            target: HomeFragment
        ) = ViewModelProvider(target, factory).get(HomeViewModel::class.java)
    }
}

@MustBeDocumented
@Target(
    AnnotationTarget.FUNCTION,
    AnnotationTarget.PROPERTY_GETTER,
    AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)

 kotlin_version = ‘1.3.72'
 dagger_version = ‘2.27’

 gradle:3.6.3

class SaveMyHeroViewModelFactory @Inject constructor(
    private val creators:  @JvmSuppressWildcards Map<Class<out ViewModel>, Provider<ViewModel>>
) : ViewModelProvider.Factory {
.......
@Module
abstract class ViewModelBuilderModule {
    @Binds
    abstract fun bindViewModelFactory(factory: SaveMyHeroViewModelFactory): ViewModelProvider.Factory
}
@Module
abstract class HomeModule {

    @ContributesAndroidInjector(modules = [ViewModelBuilderModule::class])
    internal abstract fun bind(): HomeFragment

    @Binds
    @IntoMap
    @ViewModelKey(HomeViewModel::class)
    internal abstract fun provideHomeViewModel(viewModel: HomeViewModel): ViewModel
}
@Singleton
@Component(modules = [AndroidSupportInjectionModule::class, HomeModule::class, ...])
interface SaveMyHeroApplicationComponent : AndroidInjector<SaveMyHeroApplication> {

    @Component.Factory
    interface Factory {
        fun create(@BindsInstance context: Context): SaveMyHeroApplicationComponent
    }
}