是否可以在androidx.navigation.NavController中使用DI

时间:2019-03-06 15:03:03

标签: android dependency-injection dagger-2 android-architecture-components androidx

因此,其标题反映了问题。 要获得导航控制器(androidx.navigation.NavController)上的链接,通常我们使用以下代码:

NavController navController = Navigation.findNavController(this, R.id.nav_host_frag);

是否可以使用Dagger2框架注入 NavController? (findNavController需要活动或视图引用) 也许这是一个愚蠢的问题,没有人注入androidx.navigation.NavController,但是尽管如此,我还是决定要在我的假设中确定这个问题。谢谢你

3 个答案:

答案 0 :(得分:1)

我不明白为什么在有找到方法的地方要注入NavController的原因,由于持有对{{1}的引用,我也会担心使用依赖注入}。

鉴于您正在使用Activity,通常可以通过以下方法找到控制器:

Activity

现在,如果我们看一下方法private val navController: NavController by lazy { findNavController(R.id.main_container) } 的源代码,您会注意到它使用了扩展功能和findNavController()

Navigation.findNavController(this, viewId)

我要做的唯一补充是创建另一个扩展功能,以方便从/** * Find a [NavController] given the id of a View and its containing * [Activity]. * * Calling this on a View that is not a [NavHost] or within a [NavHost] * will result in an [IllegalStateException] */ fun Activity.findNavController(@IdRes viewId: Int): NavController = Navigation.findNavController(this, viewId) 导航。

Fragment

然后您可以在片段中简单使用:

fun Fragment.navigate(resId: Int, bundle: Bundle? = null) {
    NavHostFragment.findNavController(this).navigate(resId, bundle)
}

答案 1 :(得分:0)

为什么不行?您可以像将其他任何对象一样将其添加到组件中

  • 通过@BindsInstance通过Component.Builder或带有参数的模块
  • 通过带有注释的方法@Provides返回

使用带有@Provides注释的方法,您还需要在组件中同时具有“活动”或“视图”。根据您使用Dagger的方式,通常会提供特定的Activity,因此您可以使用它,例如对于带有MyActivityComponent的{​​{1}},您只需在模块中将其返回

MyActivity

答案 2 :(得分:0)

我已经在https://stackoverflow.com/a/60061872/789110

中回答了这个问题

简而言之,

  • 通过通常的匕首手段提供NavController,例如:
   @Provides
    fun providesNavController(activity: MainActivity): NavController {
        return activity.supportFragmentManager.findFragmentById(R.id.main_content).findNavController()
    }
  • NavController注入onAttach
  • 懒惰地注入NavController 以避免在Android重新创建Activity到可以检索NavController的时间之间出现竞争情况:
    @Inject
    lateinit var navController: Provider<NavController>