作者:YANLIUPING | 来源:互联网 | 2022-12-26 17:37
我不明白为什么我会收到此错误:
Error:(12, 2) error: [dagger.android.AndroidInjector.inject(T)] java.util.Map,? extends javax.inject.Provider> cannot be provided without an @Provides-annotated method.
public abstract interface ApplicationComponent {
^
java.util.Map,? extends javax.inject.Provider> is injected at
com.chintansoni.android.architecturecomponentsblueprint.viewmodel.KotlinViewModelFactory.(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
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? {
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)
KotlinViewModelFactory.kt
@Singleton
class KotlinViewModelFactory @Inject constructor(private val creators: Map, Provider>) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun create(modelClass: Class): T {
var creator: Provider? = 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)
}
}
}
我已经浪费了很多时间在我的代码中找到错误,如果有人可以帮助我.:(
1> Chintan Soni..:
我只是缺少补充@JvmSuppressWildcards
前Provider
@Singleton
class KotlinViewModelFactory @Inject constructor(private val creators: Map, @JvmSuppressWildcards Provider>) : ViewModelProvider.Factory {
...
}
愿上帝用Kotlin + Dagger帮助我们所有人:)
我写了一篇文章来解决Dagger这个迷宫,以便让开发人员轻松生活:
https://medium.com/simform-engineering/stabbing-the-dagger-in-kotlin-merely-in-4-mins-977dba02fade