gpt4 book ai didi

android - Kotlin + Dagger 2 : cannot be provided without an @Provides-annotated method

转载 作者:IT老高 更新时间:2023-10-28 13:32:13 28 4
gpt4 key购买 nike

我不明白为什么会出现此错误:

Error:(12, 2) error: [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
public abstract interface ApplicationComponent {
^
java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at
com.chintansoni.android.architecturecomponentsblueprint.viewmodel.KotlinViewModelFactory.<init>(creators)
com.chintansoni.android.architecturecomponentsblueprint.viewmodel.KotlinViewModelFactory is injected at
com.chintansoni.android.architecturecomponentsblueprint.view.activity.SplashActivity.viewModelFactory
com.chintansoni.android.architecturecomponentsblueprint.view.activity.SplashActivity is injected at
dagger.android.AndroidInjector.inject(arg0)

KotlinApplication.kt

class KotlinApplication : Application(), HasActivityInjector {

@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>

override fun onCreate() {
super.onCreate()
initializeLogger()
initializeAppInjector()
}

private fun initializeAppInjector() {
AppInjector.init(this)
}

private fun initializeLogger() {
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
}

override fun activityInjector(): DispatchingAndroidInjector<Activity>? {
return dispatchingAndroidInjector
}
}

AppInjector.kt

object AppInjector {
fun init(kotlinApplication: KotlinApplication) {
DaggerApplicationComponent.builder()
.application(kotlinApplication)
.build()
.inject(kotlinApplication)

kotlinApplication.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {

override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
handleActivity(activity)
}

override fun onActivityStarted(activity: Activity) {

}

override fun onActivityResumed(activity: Activity) {

}

override fun onActivityPaused(activity: Activity) {

}

override fun onActivityStopped(activity: Activity) {

}

override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {

}

override fun onActivityDestroyed(activity: Activity) {

}
})
}

private fun handleActivity(activity: Activity) {
if (activity is HasSupportFragmentInjector) {
AndroidInjection.inject(activity)
}
(activity as? FragmentActivity)?.supportFragmentManager?.registerFragmentLifecycleCallbacks(
object : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentCreated(fm: FragmentManager, f: Fragment,
savedInstanceState: Bundle) {
if (f is Injectable) {
AndroidSupportInjection.inject(f)
}
}
}, true)
}
}

ApplicationComponent.kt

@Singleton
@Component(modules = [(AndroidSupportInjectionModule::class), (AppModule::class), (SplashActivityModule::class)])
interface ApplicationComponent {

@Component.Builder
interface Builder {

@BindsInstance
fun application(application: Application): Builder

fun build(): ApplicationComponent
}

fun inject(kotlinApplication: KotlinApplication)
}

AppModule.kt

@Module(includes = [(ViewModelModule::class)])
class AppModule {
@Singleton
@Provides
fun provideApiService(): ApiService {
return Retrofit.Builder()
.baseUrl("https://randomuser.me/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(LiveDataCallAdapterFactory())
.build()
.create(ApiService::class.java)
}
}

ViewModelModule.kt

@Module
abstract class ViewModelModule {

@Binds
@IntoMap
@ViewModelKey(SplashViewModel::class)
abstract fun bindSplashViewModel(splashViewModel: SplashViewModel): ViewModel

@Binds
abstract fun bindViewModelFactory(kotlinViewModelFactory: KotlinViewModelFactory): ViewModelProvider.Factory
}

ViewModelKey.kt

@MustBeDocumented
@kotlin.annotation.Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
@MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)

KotlinViewModelFactory.kt

@Singleton
class KotlinViewModelFactory @Inject constructor(private val creators: Map<Class<out ViewModel>, Provider<ViewModel>>) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
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 {
return creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}

如果有人可以帮助我解决此问题,我已经浪费了大量时间来查找代码中的错误。 :(

最佳答案

我只是想添加 @JvmSuppressWildcards之前 Provider<ViewModel>

@Singleton
class KotlinViewModelFactory @Inject constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {
...
}

愿上帝帮助我们所有人使用 Kotlin + Dagger :)

我写了一篇文章来解决这个Dagger的迷宫,让开发者的生活更轻松:

https://medium.com/simform-engineering/stabbing-the-dagger-in-kotlin-merely-in-4-mins-977dba02fade

关于android - Kotlin + Dagger 2 : cannot be provided without an @Provides-annotated method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48959619/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com