我想通过匕首提供viewmodel,所以我使用的是具有地图多重绑定的ViewModelProviderFactory。这是ViewModelProviderFactory.kt的代码:
@Singleton
class ViewModelProviderFactory @Inject constructor(private val viewModels: MutableMap<Class<out ViewModel>, Provider<ViewModel>>) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
}
这是我的ViewModelFactoryModule.kt:
@Module
abstract class ViewModelFactoryModule {
@Binds
abstract fun bindViewModelFactory(providerFactory: ViewModelProviderFactory) : ViewModelProvider.Factory
}
这是我的ViewModelKey.kt:
@Documented
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value : KClass<out ViewModel>) {
}
我想将AuthViewModel添加到名为Login的活动中,这是我的AuthViewModelModule.kt:
@Module
abstract class AuthViewModelModule {
@Binds
@IntoMap
@ViewModelKey(AuthViewModel::class)
abstract fun bindAuthViewModel(viewModel : AuthViewModel) : ViewModel
}
这是Login.kt:
class Login : AppCompatActivity() {
@Inject
lateinit var providerFactory : ViewModelProviderFactory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val api = Api.instance
val repository = UserRepository(api)
val factory = AuthViewModelFactory(repository)
val binding: ActivityLoginBinding =
DataBindingUtil.setContentView(this, R.layout.activity_login)
val viewModel = ViewModelProvider(this, providerFactory).get(AuthViewModel::class.java)
binding.viewmodel = viewModel
}
}
这是我的AppComponent.kt
@Singleton
@Component(
modules = [
AndroidSupportInjectionModule::class,
ActivityBuildersModule::class,
AppModule::class,
ViewModelFactoryModule::class
]
)
interface AppComponent : AndroidInjector<BaseApplication> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application) : Builder
fun build() : AppComponent
}
}
和我的ActivityBuildersModule.kt:
@Module
abstract class ActivityBuildersModule {
@ContributesAndroidInjector(
modules = [AuthViewModelModule::class]
)
abstract fun contributeLogin() : Login
}
代替注入所有这些,我因没有提供而出错,这是我现在得到的错误:
java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
com.kreeti.gogal.viewmodels.ViewModelProviderFactory(viewModels)
com.kreeti.gogal.viewmodels.ViewModelProviderFactory is injected at
com.kreeti.gogal.di.ViewModelFactoryModule.bindViewModelFactory(providerFactory)
androidx.lifecycle.ViewModelProvider.Factory is injected at
com.kreeti.gogal.ui.auth.Login.providerFactory
com.kreeti.gogal.ui.auth.Login is injected at
您应该注入viewModel类的构造方法例:@注入公共AuthViewModel(){}它应该工作正常。