我正在尝试使用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)
}
我的appModule:
@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.
到目前为止,我在论坛上什么都找不到,所以如果您能告诉我我在做什么错,我将不胜感激。另外我还注意到,当我尝试在“活动”中将视图模型附加到绑定对象时,我会遇到类型不匹配的情况(它显示了不完整的包名称为必需的类型)
答案 0 :(得分:0)
您的绑定是无操作的,因为您返回的是与参数传递的类型相同的类型,因此请更改返回类型
之前:
travelersMinus(evnet: Event){
this.changeCount -= 1;
}
之后:
@Binds
@IntoMap
@ViewModelKey(ModeMenuViewModel::class)
abstract fun bindModeMenuViewModel(modeMenuViewModel: ModeMenuViewModel): ModeMenuViewModel
答案 1 :(得分:0)
最后我找到了解决方案。 Dagger的包裹名称从大写字母开始出现问题。当我将所有包名称都更改为驼峰式时,一切开始起作用。