如何通过Dagger Hilt在Composable与多Activity间共享同一ViewModel实例
如何用Dagger Hilt在多个Activity间共享ViewModel实例
默认情况下,ViewModel的作用域绑定在所属的ViewModelStoreOwner(比如单个Activity),所以不同Activity拿到的是各自的实例。要实现跨Activity共享同一个ViewModel,有两种成熟方案:
方案一:绑定到Application级作用域
利用Application作为全局的ViewModelStoreOwner,让ViewModel生命周期与应用一致,所有组件都能获取同一实例。
步骤:
- 定义ViewModel:使用
@HiltViewModel标记,构造函数通过Hilt注入依赖
@HiltViewModel class SharedViewModel @Inject constructor( private val someDependency: SomeDependency ) : ViewModel() { // 业务逻辑 }
- 提供单例ViewModel实例:在Hilt的SingletonComponent模块中,将ViewModel声明为单例
@Module @InstallIn(SingletonComponent::class) object SharedViewModelModule { @Provides @Singleton fun provideSharedViewModel( someDependency: SomeDependency ): SharedViewModel { return SharedViewModel(someDependency) } }
- 在组件中获取实例:
- 在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 } }
- 在ActivityA的Composable中,指定
注意点:
- ViewModel生命周期与应用完全绑定,不会随Activity销毁而回收,需注意内存占用,避免持有大量无效数据。
方案二:自定义跨Activity作用域
通过自定义ViewModelStoreOwner容器,灵活控制ViewModel的作用范围,适合需要在特定场景下共享(而非全局)的情况。
步骤:
- 定义自定义作用域:
@Scope @Retention(AnnotationRetention.RUNTIME) annotation class CrossActivityScoped
- 实现全局ViewModelStoreOwner容器:
class CrossActivityViewModelStoreOwner : ViewModelStoreOwner { private val viewModelStore = ViewModelStore() override fun getViewModelStore(): ViewModelStore = viewModelStore companion object { val instance: CrossActivityViewModelStoreOwner by lazy { CrossActivityViewModelStoreOwner() } } }
- 在Hilt模块中提供容器实例:
@Module @InstallIn(SingletonComponent::class) object CrossActivityModule { @Provides @CrossActivityScoped fun provideCrossActivityStoreOwner(): CrossActivityViewModelStoreOwner { return CrossActivityViewModelStoreOwner.instance } }
- 在组件中获取实例:
- 在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 } }
- 在ActivityA的Composable中:
优势:
- 可手动调用
viewModelStore.clear()清理ViewModel,更灵活控制生命周期。
内容的提问来源于stack exchange,提问作者joghm
相关产品推荐
相关产品推荐

