Dagger-Hilt中如何提供Activity实例以注入ViewModel构造函数?
ViewModel构造注入需要Activity实例的解决方案
原则上禁止在ViewModel中持有Activity实例,ViewModel生命周期长于Activity,持有强引用会直接导致内存泄漏,属于违反Android架构设计规范的行为。如果确实有相关需求,可按以下场景选择对应方案:
方案1:使用辅助注入传入Activity(仅用于临时操作,不存储)
如果仅需要在ViewModel初始化时一次性调用Activity的相关方法,不需要长期持有,可以使用Dagger/Hilt的辅助注入能力,无需在Module中预先提供Activity实例:
- 给ViewModel构造函数添加
@AssistedInject注解,替换原有@Inject - 给构造函数中的Activity参数添加
@Assisted注解 - 定义辅助注入工厂:
@AssistedFactory interface MyViewModelFactory { fun create(@Assisted activity: AppCompatActivity): MyViewModel }
- 在Activity中注入工厂,创建ViewModel时传入当前Activity实例:
@AndroidEntryPoint class MyActivity : AppCompatActivity() { @Inject lateinit var viewModelFactory: MyViewModelFactory private val viewModel: MyViewModel by viewModels { object : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun <T : ViewModel> create(modelClass: Class<T>): T { return viewModelFactory.create(this@MyActivity) as T } } } }
方案2:事件回调解耦(最推荐)
从架构层面彻底解耦ViewModel和Activity,完全避免持有引用风险:
- ViewModel内部定义事件类型,通过
SharedFlow/LiveData发射事件 - Activity侧观察事件,收到事件后执行需要Activity实例的操作(弹框、跳转、权限申请等)
代码示例:
// ViewModel层 class MyViewModel @Inject constructor( // 其他注入参数 ) : ViewModel() { private val _event = MutableSharedFlow<MyEvent>() val event = _event.asSharedFlow() suspend fun triggerShowDialog() { _event.emit(MyEvent.ShowConfirmDialog) } } sealed class MyEvent { object ShowConfirmDialog : MyEvent() } // Activity层 lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.event.collect { event -> when(event) { is MyEvent.ShowConfirmDialog -> { // 用当前Activity实例弹Dialog AlertDialog.Builder(this@MyActivity) .setMessage("提示") .show() } } } } }
方案3:仅需要Context时注入Activity Context
如果你的需求只是需要Context而不是Activity实例本身,可直接注入Hilt提供的标记@ActivityContext的Context,无需自行在Module中提供:
class MyViewModel @Inject constructor( @ActivityContext private val context: Context, // 其他注入参数 ) : ViewModel() { // 直接使用context即可,Hilt会自动绑定当前Activity的上下文 }
特殊场景必须持有Activity引用时,一定要使用弱引用
WeakReference<Activity>包裹,且在Activity销毁时及时清空,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Kaium Hossain
相关产品推荐
相关产品推荐

