尝试使用Dagger2和Kotlin将ViewModelProvider注入Activity时出错

时间:2017-11-06 20:46:04

标签: android dependency-injection kotlin dagger-2

我在尝试将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()
}

我一直在关注来自Google存储库的Android架构组件示例,我认为所有内容似乎与该实施方案类似,所以我不知道为什么这不起作用。

当我尝试将Application注入MainAcitvity然后它正在工作时,问题肯定是ViewModelProvider.Factory,但遗憾的是我没有&#39}。知道问题所在。

1 个答案:

答案 0 :(得分:10)

我的猜测是你错过了AndroidSupportInjectionModule。将其添加到AppComponent中的模块列表中。我无法真正告诉您,因为您没有发布您的BaseActivity。

参考: https://github.com/google/dagger/issues/783