我是dagger的新手,并想将其用于注入ViewModels(以及其他对象,例如存储库)。当我尝试编译应用程序时,显示此错误:
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]
也许有一个愚蠢的错误阻止了编译。
匕首组件:
@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:
@Module
class AppModule {
@Inject
lateinit var app: Application
@Provides
@Singleton
fun provideAppContext(): Context = app.applicationContext
}
ActivityModule:
@Module
abstract class ActivityModule {
@ContributesAndroidInjector
abstract fun bindMainActivity(): MainActivity
@ContributesAndroidInjector
abstract fun contributeMainFrament(): MainFragment
}
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:
@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)
}
}
}
应用程序类:
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(请注意,它从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)
答案 0 :(得分:1)
我在合并Android X
和Kotlin version 1.3.0
时遇到相同的问题,Dagger无法创建MultiBindings
。为了解决这个问题,我只是按照以下步骤操作:
a)将build.gradle
文件上的Kotlin版本更新为1.3.31 :
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin: 1.3.31"
}
b)清理并重建项目,为此,请在终端中执行以下命令:
$ gradle clean build
或使用gradle包装器:
$ ./gradlew clean build
答案 1 :(得分:0)
我尝试将kotlin-gradle-plugin
更新为1.3.31
,但对我来说不起作用。
花了一些时间在互联网上之后,我发现了以下对我有用的解决方案。
尝试在@JvmSuppressWildcards
之前添加Provider<ViewModel>
,如下所示:
@Singleton
@Provides
fun provideViewModelFactory(creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>): ViewModelFactory {
return ViewModelFactory(creators)
}
在ViewModelFactory
中也是如此。
class ViewModelFactory(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) :
ViewModelProvider.Factory