android - ViewModel 中的 Kotlin Dagger 字段注入(inject)引发 Dagger/Binding 异常

标签 android kotlin dagger-2

我已关注this tutorial为了在我的 View 模型中进行 DI。但我目前陷入困境。

我为我的 View 模型创建了一个 ViewModelFactory,如下所示:

class HomeViewModelFactory @Inject constructor(
    private val creators: Map<Class<out ViewModel>,
            Provider<ViewModel>>
): ViewModelProvider.Factory{

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return creators[modelClass]?.get() as T
    }
}

后跟 ViewModel:

class HomeViewModel @Inject constructor(private val songsRepository: SongsRepository): ViewModel()

对于 DI,我创建了两个组件。一个是我的主应用程序组件,另一个是依赖于主应用程序的组件。

@Singleton
@Component(modules = [AppModule::class])
public interface AppComponent {
    fun songRepository(): SongsRepository
    fun libraryManager(): LibraryManager
    fun inject(mainActivity: MainActivity)
}


@Module
public class AppModule(val application: Application){

    @Provides @Singleton
    fun providesApplication(): Application{
        return application
    }

    @Provides @Singleton
    fun providesLibraryManager(): LibraryManager {
        return LibraryManager(application)
    }

    @Provides @Singleton
    fun providesSongRepository(libraryManager: LibraryManager): SongsRepository {
        return SongsRepository(libraryManager)
    }
}

我的 ViewModelModule 如下:

@Module
public class ViewModelModule {

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

    @AppScope
    @Provides
    fun providesHomeViewModelFactory(providerMap: Map<Class<out ViewModel>, Provider<ViewModel>>): HomeViewModelFactory {
        return HomeViewModelFactory(providerMap)
    }

    @AppScope
    @IntoMap
    @Provides
    @ViewModelKey(HomeViewModel::class)
    fun providesHomeViewModel(songsRepository: SongsRepository): HomeViewModel{
        return HomeViewModel(songsRepository)
    }
}

@AppScope
@Component(modules = [ViewModelModule::class], dependencies = [AppComponent::class])
public interface ViewModelComponent {
    fun homeViewModelFactory(): HomeViewModelFactory
    fun homeViewModel(): HomeViewModel
    fun inject(homeFragment: HomeFragment)
}

我收到的错误是这样的:

error: [Dagger/MissingBinding] java.util.Map,? extends javax.inject.Provider> cannot be provided without an @Provides-annotated method.

我真的不知道为什么会发生这种情况,因为我的所有类都有 @Inject 构造函数。 Dagger 的文档也没有帮助我。如果您能就此事向我提出建议,我将不胜感激。

最佳答案

错误信息表明以下代码错误:

fun providesHomeViewModelFactory(providerMap: Map<Class<out ViewModel>, Provider<ViewModel>>): HomeViewModelFactory {
    return HomeViewModelFactory(providerMap)
}

应该是

fun providesHomeViewModelFactory(providerMap: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>): HomeViewModelFactory {
    return HomeViewModelFactory(providerMap)
}

因为Map的签名界面是Map<K, out V> ,这意味着 Map<..., Provider<ViewModel>>将被编译为 Map<..., ? extends Provider<ViewModel>> Java 代码,因此您向 dagger 请求后一种,但它的对象图中只有前一种,然后编译器会向您抛出错误。

关于android - ViewModel 中的 Kotlin Dagger 字段注入(inject)引发 Dagger/Binding 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57119921/

相关文章:

android - setSkipWebLineCount(...) 似乎不适用于 MPAndroidChart

android - 模块 'app' : platform 'android-28' not found , 安卓工作室 3.6.3

java - 如何让 OkHttpClient 遵守 REST API 速率限制?

java - 了解 Dagger2 子组件

android - kotlin 中的 Dagger2 编译问题

使用 Phonegap/Cordova 收听声音和记录音量的 Android 应用程序

android - 如何使用 Android 的本地网络服务发现找到所有可用的服务

java - 了解Dagger 2应用架构

android - Here Map Offline 逐路导航

android - 使用 Android 数据绑定(bind)时禁用 Kotlin 合成绑定(bind)