首页 > 解决方案 > Dagger 提供依赖于活动视图的依赖项

问题描述

我有一个带有导航抽屉的活动,里面有很多片段。我使用架构组件中的导航库。在我必须写的每个片段中navController = Navigation.findNavController(activity!!, R.id.fragment_container)。我想摆脱这个样板代码。所以我决定用 Dagger 注入它。

@Module
class MainActivityModule {
    @ActivityScope
    @Provides
    fun provideNavController(activity: MainActivity): NavController {
        return Navigation.findNavController(activity, R.id.fragment_container)
    }
}

@Suppress("unused")
@Module
abstract class ActivityBuildersModule {
    @ActivityScope
    @ContributesAndroidInjector(
            modules = [MainActivityModule::class, MainActivityFragmentBuildersModule::class])
    abstract fun contributeMainActivity(): MainActivity
}

注入片段工作正常,但是当我尝试注入活动应用程序崩溃时:

09-19 19:22:37.152 22342-22342/com.dmitrysimakov.gymlab
    E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dmitrysimakov.gymlab, PID: 22342
java.lang.RuntimeException: Unable to start activity
    ComponentInfo{com.dmitrysimakov.gymlab/com.dmitrysimakov.gymlab.MainActivity}:
    java.lang.IllegalArgumentException: ID does not reference a View inside this Activity
    .....

所以我必须navController = Navigation.findNavController(activity!!, R.id.fragment_container)在活动中复制。有没有更优雅的方法来做到这一点?

标签: androiddagger-2android-architecture-components

解决方案


活动导致应用程序崩溃,因为在provideNavController调用时您尚未设置内容视图setContentView

第 1 步:如果您的扩展DaggerAppCompatActivity复制其代码并扩展 AppCompatActivity,否则只需执行第 2 步。

第2步:AndroidInjection.inject(this)onCreate方法中移行setContentView(...)

但是请注意,根据我的经验,这可能会导致类似这样的其他问题,因此为了让您从活动中获取导航控制器,最好的选择可能只是使用扩展,如果您'android.arch.navigation:navigation-ui-ktx:1.0.0-alpha05'在 build.gradle 中有依赖项,实际上有一个内置的:

findNavController(R.id.fragment_container)

因此,对于您的活动,您可以使用此扩展程序,无论如何,如果您使用推荐的单一活动方式,在大多数情况下,您将从片段中获得导航,并且您仍然可以使用匕首注入


推荐阅读