尝试使用Dagger2和Kotlin将ViewModelProvider注入到Activity时出错
在尝试将ViewModelProvider.Factory
注入到Activity
时收到以下错误:
e: D:\AndroidStudioProjects\VolleyballStats\app\build\tmp\kapt3\stubs\debug\com\example\kamil\volleyballstats\di\AppComponent.java:6: error: [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.Class<? extends android.support.v4.app.Fragment>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> cannot be provided without an @Provides-annotated method. e: e: public abstract interface AppComponent extends dagger.android.AndroidInjector<com.example.kamil.volleyballstats.VolleyballStatsApp> { e: ^ e: java.util.Map<java.lang.Class<? extends android.support.v4.app.Fragment>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> is injected at e: dagger.android.DispatchingAndroidInjector.<init>(injectorFactories) e: dagger.android.DispatchingAndroidInjector<android.support.v4.app.Fragment> is injected at e: dagger.android.support.DaggerAppCompatActivity.supportFragmentInjector e: com.example.kamil.volleyballstats.views.main.MainActivity is injected at e: dagger.android.AndroidInjector.inject(arg0)
我创建了非常标准的Dagger2实现,如下所示:
@Singleton @Component(modules = arrayOf( AndroidInjectionModule::class, AppModule::class, MainActivityModule::class)) interface AppComponent : AndroidInjector<VolleyballStatsApp> { @Component.Builder interface Builder { @BindsInstance fun application(application: VolleyballStatsApp): Builder fun build(): AppComponent } override fun inject(app: VolleyballStatsApp) } @Module abstract class ViewModelModule { @Binds @IntoMap @ViewModelKey(MainViewModel::class) abstract fun bindMainViewModel(viewModel: MainViewModel): ViewModel @Binds abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory } @Module(includes = arrayOf(ViewModelModule::class)) class AppModule { @Provides fun provideDisposable(): CompositeDisposable { return CompositeDisposable() } } @Module internal abstract class MainActivityModule { @ContributesAndroidInjector(modules = arrayOf(FragmentBuilders::class)) internal abstract fun contributeMainActivity(): MainActivity } @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) @MapKey internal annotation class ViewModelKey(val value: KClass<out ViewModel>) class ViewModelFactory @Inject constructor(private val creators: @JvmSuppressWildcards Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>> ) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { var creator: Provider<out ViewModel>? = creators[modelClass] if (creator == null) { for ((key, value) in creators) { if (modelClass.isAssignableFrom(key)) { creator = value break } } } if (creator == null) { throw IllegalArgumentException("unknown model class " + modelClass) } try { @Suppress("UNCHECKED_CAST") return creator.get() as T } catch (e: Exception) { throw RuntimeException(e) } } }
我的MainActivity
定义如下:
class MainActivity : BaseActivity() { @Inject lateinit var viewModelFactory: ViewModelProvider.Factory private lateinit var viewModel: MainViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) viewModel = ViewModelProviders.of(this, viewModelFactory).get(MainViewModel::class.java) } }
这里是MainViewModel
类:
class MainViewModel @Inject constructor(private val disposable: CompositeDisposable) : ViewModel() { }
最后是App
类:
class VolleyballStatsApp : DaggerApplication() { override fun applicationInjector() = DaggerAppComponent.builder() .application(this) .build() }
我一直在关注谷歌资源库中的Android Architecture Components Sample,我认为一切似乎都与该实现类似,所以我不明白为什么这样做不起作用。
当我试图注入Application
MainAcitvity
然后它的工作,所以问题是肯定与ViewModelProvider.Factory
,但不幸的是,我不知道问题在哪里。
我的猜测是你错过了AndroidSupportInjectionModule
。 将它添加到AppComponent
中的模块列表中。 我无法确定,因为您没有发布您的BaseActivity。
参考: https : //github.com/google/dagger/issues/783 。