简体   繁体   English

注入ViewModels时出现Dagger MissingBinding错误

[英]Dagger MissingBinding error when injecting ViewModels

I'm new to dagger and want to use it for injecting ViewModels (along with other objects such as repositories). 我是dagger的新手,并想将其用于注入ViewModels(以及其他对象,例如存储库)。 When I try to compile the app this error is shown: 当我尝试编译应用程序时,显示此错误:

e: C:\Project\...\app\build\tmp\kapt3\stubs\debug\com\myapp\di\AppComponent.java:16: 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.

public abstract interface AppComponent {
                ^
      java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
          com.myapp.di.ViewModelFactory(viewModels)
      com.myapp.di.ViewModelFactory is injected at
          com.myapp.di.ViewModelModule.bindViewModelFactory(factory)
      androidx.lifecycle.ViewModelProvider.Factory is injected at
          com.myapp.ui.activity.MainActivity.viewModelFactory
      com.myapp.ui.activity.MainActivity is injected at
          dagger.android.AndroidInjector.inject(T) [com.myapp.di.AppComponent ? com.myapp.di.ActivityModule_ContributeMainActivity.MainActivitySubcomponent]
  The following other entry points also depend on it:
      dagger.android.AndroidInjector.inject(T) [com.myapp.di.AppComponent ? com.myapp.di.ActivityModule_ContributeItemsFrament.ItemsFragmentSubcomponent]

Maybe there is one silly mistake that prevents compilation. 也许有一个愚蠢的错误阻止了编译。

Dagger component: 匕首组件:

@Singleton
@Component(modules = [AndroidSupportInjectionModule::class, AppModule::class, DatabaseModule::class, ViewModelModule::class, ActivityModule::class])
interface AppComponent {

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: MyCustomApplication): Builder

        fun build(): AppComponent
    }

    fun inject(app: MyCustomApplication)
}

AppModule: AppModule:

@Module
class AppModule {

    @Inject
    lateinit var app: Application

    @Provides
    @Singleton
    fun provideAppContext(): Context = app.applicationContext
}

ActivityModule: ActivityModule:

@Module
abstract class ActivityModule {

    @ContributesAndroidInjector
    abstract fun bindMainActivity(): MainActivity

    @ContributesAndroidInjector
    abstract fun contributeMainFrament(): MainFragment
}

ViewModelModule: ViewModelModule:

@Module
abstract class ViewModelModule {

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

    @Binds
    @IntoMap
    @ViewModelKey(MainViewModel::class)
    abstract fun mainViewModel(mainViewModel: MainViewModel): ViewModel
}

ViewModelFactory: ViewModelFactory:

@Singleton
class ViewModelFactory
@Inject constructor(private val viewModels: MutableMap<Class<out ViewModel>, Provider<ViewModel>>)
: ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        val creator = viewModels[modelClass]
                ?: viewModels.asIterable().firstOrNull { modelClass.isAssignableFrom(it.key) }?.value
                ?: throw IllegalArgumentException("unknown model class $modelClass")
        return try {
            creator.get() as T
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
    }
}

The application class: 应用程序类:

class MyCustomApplication : Application(), HasActivityInjector, HasSupportFragmentInjector {

    @Inject lateinit var activityInjector: DispatchingAndroidInjector<Activity>

    override fun onCreate() {
        super.onCreate()

        DaggerMainComponent
                .builder()
                .application(this)
                .build()
                .inject(this)
    }

    override fun activityInjector() = activityInjector
}

MainViewModel ( note that it extends from AndroidViewModel and requires an application context ): MainViewModel( 请注意,它是从AndroidViewModel扩展而来的,需要应用程序上下文 ):

class MainViewModel @Inject constructor(app: Application, private val repository: MainRepository)
    : AndroidViewModel(app) {

MainActivity: 主要活动:

class MainActivity : BaseActivity() {

    @Inject
    internal lateinit var viewModelFactory: ViewModelProvider.Factory
    private lateinit var viewModel: MainViewModel

    override fun onCreate(savedState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedState)
        viewModel = ViewModelProviders.of(this,viewModelFactory).get(MainViewModel::class.java)

I faced same issue combining Android X and Kotlin version 1.3.0 , Dagger won't be able to create MultiBindings . 我遇到了结合Android XKotlin version 1.3.0同样问题,Dagger无法创建MultiBindings To solve the problem I just followed next steps: 为了解决这个问题,我只是遵循以下步骤:

a) Update Kotlin version to 1.3.31 on build.gradle file: a)在build.gradle文件上将Kotlin版本更新为1.3.31

dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin: 1.3.31"
}

b) Clean and rebuild the project, to do so, execute the following command in a terminal: b) 清理并重建项目,为此,请在终端中执行以下命令:

$ gradle clean build 

or if using gradle wrapper: 或者使用gradle包装器:

 $ ./gradlew clean build

I have tried updating the kotlin-gradle-plugin to 1.3.31 but it didn't work for me. 我尝试将kotlin-gradle-plugin更新为1.3.31但对我而言不起作用。

After spending some time on the internet, I have found the following solution which is working for me. 在互联网上花费了一些时间之后,我发现了以下对我有用的解决方案。

Try adding @JvmSuppressWildcards before Provider<ViewModel> like following: 尝试在Provider<ViewModel>之前添加@JvmSuppressWildcards ,如下所示:

@Singleton
@Provides
fun provideViewModelFactory(creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>): ViewModelFactory {
    return ViewModelFactory(creators)
}

And in ViewModelFactory as well. 并且在ViewModelFactory中也是如此。

class ViewModelFactory(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) :
        ViewModelProvider.Factory

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM