如何使用 Hilt 将对象实例的范围限定到 Jetpack Compose 导航图生命周期?

问题描述 投票:0回答:1

假设我有一个带有功能模块的多模块 Jetpack Compose 项目,并且我想将一些对象实例的范围限制到功能生命周期。例如,我想将

AuthRepo
实例的范围限定为
AuthFeature
生命周期,并在用户登录后立即将其从内存中删除。我们还假设我的功能由几个可组合的屏幕组成。

所以,我的

MainActivity
看起来像这样:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ...
            NavHost(navController = navController, startDestination = *AuthFeature graph*) {
               navigation(*AuthFeature graph*) {
                   composable(*First Screen*) { backStackEntry ->
                       val authGraphEntry = *get authGraphEntry*
                       val vm = hiltViewModel<AuthViewModel>(authGraphEntry)
                       ...
                   }

                   composable(*Second Screen*) { backStackEntry ->
                       val authGraphEntry = *get authGraphEntry*
                       val vm = hiltViewModel<AuthViewModel>(authGraphEntry)
                       ...
                   }
              }

              *Other feature graph with multiple screens*
              
         }
    }    

在这种情况下,没有问题:

AuthViewModel
(这两个屏幕都很常见)的范围仅限于
AuthFeature
图,我可以在注入
@ViewModelScoped
时使用 Hilt 的
AuthRepo
注释。因此
AuthViewModel
将在导航到其他功能(弹出到根)后被销毁,并且
AuthRepo
也将被销毁。

当我决定为每个屏幕创建一个 ViewModel 时,问题就出现了。第一个屏幕和第二个屏幕考虑使用相同的

AuthRepo
实例,但是用
AuthRepo
注释
@ViewModelScoped
会导致创建
AuthRepo
的两个实例,因为我有 2 个 ViewModel。使用
@Singleton
对其进行注释会导致为整个应用程序创建一个实例,该实例在导航到另一功能后不会被删除。

我想出了两种方法来解决这个问题:

  1. 将每个功能包含在活动中并使用

    @ActivityRetainedScoped
    。但是我想在我的项目中使用 SingleActivity 模式,所以这个解决方案对我来说无效。

  2. 使用 Dagger 及其自定义范围。但我希望有一个更简单的解决方案,无需手动组件生命周期处理,以保持代码整洁且不易出错。

另一方面,我不想为每个功能留下 1 个 ViewModel,因为有一天它可能会增长到大量代码行。有任何想法吗?如果我的一些说法有错误,请纠正我。

android android-jetpack-compose dagger-2 dagger-hilt jetpack-compose-navigation
1个回答
0
投票

Hilt 的目的是拥有一组有限的范围,适合大多数用例,但您的特定需求需要使用 Dagger 自定义范围,正如您已经猜到的那样。

© www.soinside.com 2019 - 2024. All rights reserved.