使用匕首2注入视图模型的错误
我刚刚开始学习匕首2,并试图为子组件制作子组件。我遇到了错误,找不到它来自哪里。在下面,我将写匕首的结构。
AppComponent
-AppModule
-SubcomponentsModule
--MainComponent
---MainModule
----AuthorizationComponent
-----AuthorizationModule
----UserProfileComponent
-----UserProfileModule
---ViewModelModule
-NetworkModule
Application component:
@Singleton
@Component(modules = [AppModule::class, SubcomponentsModule::class, NetworkModule::class])
interface AppComponent {
fun mainComponent(): MainComponent.Factory
}
It has SubcomponentsModule with one subcomponent so far:
@Module(subcomponents = [MainComponent::class])
class SubcomponentsModule
MainComponent:
@Subcomponent(modules = [MainModule::class, ViewModelModule::class])
interface MainComponent {
@Subcomponent.Factory
interface Factory {
fun create(): MainComponent
}
fun inject(activity: MainActivity)
fun authorizationComponent(): AuthorizationComponent.Factory
fun userProfileComponent(): UserProfileComponent.Factory
}
ViewModelModule:
@Module
abstract class ViewModelModule {
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
MainComponent has MainModule with AuthorizationComponent and UserProfileComponent:
@Module(subcomponents = [AuthorizationComponent::class, UserProfileComponent::class])
abstract class MainModule {
@Binds
@IntoMap
@ViewModelKey(MainViewModel::class)
abstract fun mainViewModel(viewModel: MainViewModel): ViewModel
}
AuthorizationComponent with AuthorizationModule:
@Subcomponent(modules = [AuthorizationModule::class])
interface AuthorizationComponent {
@Subcomponent.Factory
interface Factory {
fun create(): AuthorizationComponent
}
fun inject(fragment: AuthorizationFragment)
}
AuthorizationModule:
@Module
abstract class AuthorizationModule {
@Binds
@IntoMap
@ViewModelKey(AuthorizationViewModel::class)
abstract fun authorizationViewModel(viewModel: AuthorizationViewModel): ViewModel
}
UserProfileComponent with UserProfileModule is equivalent to AuthorizationComponent and AuthorizationModule.
当启动构建时,我会收到错误:
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
ui.base.ViewModelFactory(viewModels)
ui.base.ViewModelFactory is injected at
di.main.ViewModelModule.bindViewModelFactory(factory)
androidx.lifecycle.ViewModelProvider.Factory is injected at
ui.base.BaseActivity.viewModelFactory
ui.main.MainActivity is injected at
di.main.MainComponent.inject(ui.main.MainActivity) [di.AppComponent ? di.main.MainComponent]
The following other entry points also depend on it:
di.main.auth.AuthorizationComponent.inject(ui.auth.AuthorizationFragment) [di.AppComponent ? di.main.MainComponent ? di.main.auth.AuthorizationComponent]
di.main.userprofile.UserProfileComponent.inject(ui.userprofile.UserProfileFragment) [di.AppComponent ? di.main.MainComponent ? di.main.userprofile.UserProfileComponent]
我用于查看模型搜索的注释是:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
以及这里应该提到的最后一件事是我的ViewModeFactory:
@Singleton
class ViewModelFactory @Inject constructor(
private val viewModels: MutableMap<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
}
I just started learning Dagger 2 and trying to make subcomponent for subcomponent. I faced error and can't find where it comes from. Below I will write my dagger structure.
AppComponent
-AppModule
-SubcomponentsModule
--MainComponent
---MainModule
----AuthorizationComponent
-----AuthorizationModule
----UserProfileComponent
-----UserProfileModule
---ViewModelModule
-NetworkModule
Application component:
@Singleton
@Component(modules = [AppModule::class, SubcomponentsModule::class, NetworkModule::class])
interface AppComponent {
fun mainComponent(): MainComponent.Factory
}
It has SubcomponentsModule with one subcomponent so far:
@Module(subcomponents = [MainComponent::class])
class SubcomponentsModule
MainComponent:
@Subcomponent(modules = [MainModule::class, ViewModelModule::class])
interface MainComponent {
@Subcomponent.Factory
interface Factory {
fun create(): MainComponent
}
fun inject(activity: MainActivity)
fun authorizationComponent(): AuthorizationComponent.Factory
fun userProfileComponent(): UserProfileComponent.Factory
}
ViewModelModule:
@Module
abstract class ViewModelModule {
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
MainComponent has MainModule with AuthorizationComponent and UserProfileComponent:
@Module(subcomponents = [AuthorizationComponent::class, UserProfileComponent::class])
abstract class MainModule {
@Binds
@IntoMap
@ViewModelKey(MainViewModel::class)
abstract fun mainViewModel(viewModel: MainViewModel): ViewModel
}
AuthorizationComponent with AuthorizationModule:
@Subcomponent(modules = [AuthorizationModule::class])
interface AuthorizationComponent {
@Subcomponent.Factory
interface Factory {
fun create(): AuthorizationComponent
}
fun inject(fragment: AuthorizationFragment)
}
AuthorizationModule:
@Module
abstract class AuthorizationModule {
@Binds
@IntoMap
@ViewModelKey(AuthorizationViewModel::class)
abstract fun authorizationViewModel(viewModel: AuthorizationViewModel): ViewModel
}
UserProfileComponent with UserProfileModule is equivalent to AuthorizationComponent and AuthorizationModule.
When I launch build, I get error:
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
ui.base.ViewModelFactory(viewModels)
ui.base.ViewModelFactory is injected at
di.main.ViewModelModule.bindViewModelFactory(factory)
androidx.lifecycle.ViewModelProvider.Factory is injected at
ui.base.BaseActivity.viewModelFactory
ui.main.MainActivity is injected at
di.main.MainComponent.inject(ui.main.MainActivity) [di.AppComponent ? di.main.MainComponent]
The following other entry points also depend on it:
di.main.auth.AuthorizationComponent.inject(ui.auth.AuthorizationFragment) [di.AppComponent ? di.main.MainComponent ? di.main.auth.AuthorizationComponent]
di.main.userprofile.UserProfileComponent.inject(ui.userprofile.UserProfileFragment) [di.AppComponent ? di.main.MainComponent ? di.main.userprofile.UserProfileComponent]
The annotation I use for view models search is:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
And the last thing that should be mentioned here is my ViewModelFactory:
@Singleton
class ViewModelFactory @Inject constructor(
private val viewModels: MutableMap<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论