热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

kotlin+Dagger2:如果没有@Provide-annotated方法,则无法提供

如何解决《kotlin+Dagger2:如果没有@Provide-annotated方法,则无法提供》经验,为你挑选了1个好方法。

我不明白为什么我会收到此错误:

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..:

我只是缺少补充@JvmSuppressWildcardsProvider

@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


推荐阅读
author-avatar
YANLIUPING
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有