【发布时间】:2018-10-21 21:06:39
【问题描述】:
我正在尝试在 Android Kotlin 项目中使用 dagger 2 执行视图模型注入。到目前为止,我的项目看起来像这样。我的 AppComponent 看起来像这样
@AppScope
@Component(modules = [
ViewModelModule::class,
AndroidSupportInjectionModule::class,
AppModule::class,
BuildersModule::class
])
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application : App) : Builder
fun build() : AppComponent
}
fun inject(app: App)
}
我的应用模块:
@Module class AppModule
我还创建了 Builders 模块来提供我的视图:
@Module
abstract class BuildersModule {
@ContributesAndroidInjector
abstract fun providesMainActivity() : MainActivity
@ContributesAndroidInjector()
abstract fun providesModeMenuActivity(): ModeMenuActivity
}
我的视图模型工厂取自github project上的示例
@AppScope
class ViewModelFactory
@Inject constructor(
private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val creator = creators[modelClass] ?:
creators.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)
}
}
}
我像这样在 ViewModelModule 中绑定了工厂:
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(ModeMenuViewModel::class)
abstract fun bindModeMenuViewModel(modeMenuViewModel: ModeMenuViewModel): ModeMenuViewModel
@Binds
abstract fun bindsViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
现在一切都在构建,直到我在这样的活动之一中添加 ViewModelFacotory 注入:
class ModeMenuActivity: AppCompatActivity() {
@Inject
lateinit var vmFactory: ViewModelProvider.Factory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidInjection.inject(this)
val binding: ActivityModeMenuBinding = DataBindingUtil.setContentView(this, R.layout.activity_mode_menu)
val viewModel = ViewModelProviders.of(this, vmFactory).get(ModeMenuViewModel::class.java)
binding.ViewModel = viewModel
}
}
当我在添加 @Inject 之后构建代码时,出现以下错误:
C:\Users\Maciej\AndroidStudioProjects\AndroidMVVM\app\build\tmp\kapt3\stubs\debug\com\example\maciej\androidmvvm\di\AppComponent.java:8: error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
public abstract interface AppComponent {
^
java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at
com.example.maciej.androidmvvm.ViewModelModule.ViewModelFactory.<init>(creators)
com.example.maciej.androidmvvm.ViewModelModule.ViewModelFactory is injected at
com.example.maciej.androidmvvm.ViewModelModule.ViewModelModule.bindsViewModelFactory(factory)
android.arch.lifecycle.ViewModelProvider.Factory is injected at
com.example.maciej.androidmvvm.ui.common.ModeMenu.ModeMenuActivity.vmFactory
com.example.maciej.androidmvvm.ui.common.ModeMenu.ModeMenuActivity is injected at
dagger.android.AndroidInjector.inject(T)
component path: com.example.maciej.androidmvvm.di.AppComponent ? com.example.maciej.androidmvvm.di.BuildersModule_ProvidesModeMenuActivity.
到目前为止,我在论坛上找不到任何东西,所以如果你能告诉我我做错了什么,我将不胜感激。我还注意到,当我尝试在 Activity 中将视图模型附加到我的绑定对象时,我得到类型不匹配(它显示不完整的包名称作为所需类型)
【问题讨论】:
-
我只看了几分钟,但我认为
@ViewModelKey将您的 ViewModel 映射到 KClass,而不是 Java 类 -
可以添加
ModeMenuViewModel的代码吗?
标签: android mvvm kotlin dagger-2