You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Dagger Hilt在Composable与多Activity间共享同一ViewModel实例

如何用Dagger Hilt在多个Activity间共享ViewModel实例

默认情况下,ViewModel的作用域绑定在所属的ViewModelStoreOwner(比如单个Activity),所以不同Activity拿到的是各自的实例。要实现跨Activity共享同一个ViewModel,有两种成熟方案:

方案一:绑定到Application级作用域

利用Application作为全局的ViewModelStoreOwner,让ViewModel生命周期与应用一致,所有组件都能获取同一实例。

步骤:

  1. 定义ViewModel:使用@HiltViewModel标记,构造函数通过Hilt注入依赖
@HiltViewModel
class SharedViewModel @Inject constructor(
    private val someDependency: SomeDependency
) : ViewModel() {
    // 业务逻辑
}
  1. 提供单例ViewModel实例:在Hilt的SingletonComponent模块中,将ViewModel声明为单例
@Module
@InstallIn(SingletonComponent::class)
object SharedViewModelModule {
    @Provides
    @Singleton
    fun provideSharedViewModel(
        someDependency: SomeDependency
    ): SharedViewModel {
        return SharedViewModel(someDependency)
    }
}
  1. 在组件中获取实例:
    • 在ActivityA的Composable中,指定storeOwner为Application:
      @Composable
      fun ActivityAScreen() {
          val appContext = LocalContext.current.applicationContext
          val viewModel = hiltViewModel<SharedViewModel>(storeOwner = appContext as ViewModelStoreOwner)
          // 使用viewModel
      }
      
    • 在ActivityB中直接注入单例实例:
      @AndroidEntryPoint
      class ActivityB : AppCompatActivity() {
          @Inject
          lateinit var sharedViewModel: SharedViewModel
      
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              // 使用sharedViewModel
          }
      }
      

注意点:

  • ViewModel生命周期与应用完全绑定,不会随Activity销毁而回收,需注意内存占用,避免持有大量无效数据。

方案二:自定义跨Activity作用域

通过自定义ViewModelStoreOwner容器,灵活控制ViewModel的作用范围,适合需要在特定场景下共享(而非全局)的情况。

步骤:

  1. 定义自定义作用域:
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class CrossActivityScoped
  1. 实现全局ViewModelStoreOwner容器:
class CrossActivityViewModelStoreOwner : ViewModelStoreOwner {
    private val viewModelStore = ViewModelStore()

    override fun getViewModelStore(): ViewModelStore = viewModelStore

    companion object {
        val instance: CrossActivityViewModelStoreOwner by lazy { CrossActivityViewModelStoreOwner() }
    }
}
  1. 在Hilt模块中提供容器实例:
@Module
@InstallIn(SingletonComponent::class)
object CrossActivityModule {
    @Provides
    @CrossActivityScoped
    fun provideCrossActivityStoreOwner(): CrossActivityViewModelStoreOwner {
        return CrossActivityViewModelStoreOwner.instance
    }
}
  1. 在组件中获取实例:
    • 在ActivityA的Composable中:
      @Composable
      fun ActivityAScreen() {
          val storeOwner = remember { CrossActivityViewModelStoreOwner.instance }
          val viewModel = hiltViewModel<SharedViewModel>(storeOwner = storeOwner)
          // 使用viewModel
      }
      
    • 在ActivityB中:
      @AndroidEntryPoint
      class ActivityB : AppCompatActivity() {
          @Inject
          lateinit var storeOwner: CrossActivityViewModelStoreOwner
          private lateinit var sharedViewModel: SharedViewModel
      
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              sharedViewModel = ViewModelProvider(storeOwner)[SharedViewModel::class.java]
              // 使用sharedViewModel
          }
      }
      

优势:

  • 可手动调用viewModelStore.clear()清理ViewModel,更灵活控制生命周期。

内容的提问来源于stack exchange,提问作者joghm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:26:28