如何通过Hilt向Activity注入与Composable同实例的ViewModel?
解决方案
1. 配置ViewModel的Hilt注解
首先确保你的AccountViewModel标注@HiltViewModel,并且构造函数使用@Inject声明:
@HiltViewModel class AccountViewModel @Inject constructor( // 这里可以注入所需依赖,比如Repository等 ) : ViewModel() { // 业务逻辑实现 }
2. 给Activity添加Hilt入口注解
在MainActivity上添加@AndroidEntryPoint,让Hilt能够关联它的ViewModel生命周期:
@AndroidEntryPoint class MainActivity : ComponentActivity() { // 使用by viewModels()获取实例,这会和Composable中的实例共享 private val accountViewModel: AccountViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { // 直接调用Composable,内部的hiltViewModel()会自动绑定当前Activity的ViewModelStore AccountScreen() // 也可以显式传递ViewModel实例,逻辑更直观 // AccountScreen(accountViewModel = accountViewModel) } } }
3. 保持Composable的原有配置
你的AccountScreen无需修改,默认的hiltViewModel()会自动使用最近的ViewModelStoreOwner(也就是当前的MainActivity),因此获取到的实例和Activity中的完全一致:
@Composable fun AccountScreen(accountViewModel: AccountViewModel = hiltViewModel()) { // 业务逻辑实现 }
关于之前生成新实例的原因
- 直接用
@Inject注入ViewModel是错误的,ViewModel的生命周期由ViewModelStoreOwner(如Activity)管理,并非Hilt依赖容器直接托管,因此不能通过@Inject直接获取。 - 如果Activity未添加
@AndroidEntryPoint、ViewModel未标注@HiltViewModel,by viewModels()和hiltViewModel()会各自创建独立实例,导致无法共享。
内容的提问来源于stack exchange,提问作者AtomicStrongForce
相关产品推荐
相关产品推荐

