繁体   English   中英

匕首2,Cicerone,科特林-注入问题

[英]Dagger 2, Cicerone, Kotlin - inject problem

该代码在Java中完美地工作,但在Kotlin中有未定义的问题

问题

错误:[Dagger / MissingBinding]如果没有@Inject构造函数或@Provides注释的方法,则无法提供ru.terrakok.cicerone.Router。 公共抽象无效注入(@ org.jetbrains.annotations.NotNull()

ru.terrakok.cicerone.Router被注入com.setname.dagger2ciceronelearning.presentation.main.MainActivity.mRouter

com.setname.dagger2ciceronelearning.presentation.main.MainActivity在com.setname.dagger2ciceronelearning.di.AppComponent.inject(com.setname.dagger2ciceronelearning.presentation.main.MainActivity)处注入

AppComponent

@Singleton
@Component(modules = arrayOf(NavigationModule::class))
interface AppComponent {

    fun inject(mainActivity: MainActivity)
    fun inject(fragmentOne: FragmentOne)
    fun inject(fragmentTwo: FragmentTwo)

}

NavigationModule

@Module
class NavigationModule {

    private val firstLevelNavigation: Cicerone<Router> = Cicerone.create()
    private val secondLevelNavigation: Cicerone<Router> = Cicerone.create()

    @Provides
    @Singleton
    @Named(Navigation.ROUTER_FIRST_LEVEL)
    fun provideFirstLevelRouter(): Router = firstLevelNavigation.router

    @Provides
    @Singleton
    @Named(Navigation.ROUTER_SECOND_LEVEL)
    fun provideSecondLevelRouter(): Router = secondLevelNavigation.router

    @Provides
    @Singleton
    @Named(Navigation.NAV_HOLDER_FIRST_LEVEL)
    fun provideFirstLevelNavigatorHolder(): NavigatorHolder = firstLevelNavigation.navigatorHolder


    @Provides
    @Singleton
    @Named(Navigation.NAV_HOLDER_SECOND_LEVEL)
    fun provideSecondLevelNavigationHolder(): NavigatorHolder = secondLevelNavigation.navigatorHolder

}

LearingApp

class LearningApp : Application() {

    companion object {

        lateinit var appComponent: AppComponent

    }

    override fun onCreate() {
        super.onCreate()
        appComponent = DaggerAppComponent
            .builder()
            .build()
    }

}

主要活动

class MainActivity : AppCompatActivity() {

    @Inject
    @Named(Navigation.ROUTER_FIRST_LEVEL)
    lateinit var mRouter: Router

    @Inject
    @Named(Navigation.NAV_HOLDER_FIRST_LEVEL)
    lateinit var mNavigatorHolder: NavigatorHolder

    private lateinit var mNavigator:Navigator

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        LearningApp.appComponent.inject(this)

        mNavigator = SupportAppNavigator(this, R.id.main_container)

        mRouter.newRootScreen(Screens.FragmentOneScreen())

    }

    override fun onResume() {
        super.onResume()
        mNavigatorHolder.setNavigator(mNavigator)
    }

    override fun onPause() {
        mNavigatorHolder.removeNavigator()
        super.onPause()
    }

}

就像一个非常聪明的人曾经说过的: You need to target the annotation at the field by using @field:Named.

您可以尝试使用自定义限定词:

@Qualifier
@Retention
annotation class RouterFirstLevel

然后您的模块:

@Provides
@Singleton
@RouterFirstLevel
fun provideFirstLevelRouter(): Router = firstLevelNavigation.router

和活动:

@Inject
@RouterFirstLevel
lateinit var mRouter: Router

PS我虽然同意jbarat,注解中的字段应该有所帮助,请尝试使用字符串代替字符串常量,也许某些类型不匹配

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM