Hilt为MVVM+Jetpack Compose的RepositoryImpl注入ApplicationContext方案
结合Hilt注入实现Repository安全获取ApplicationContext的方案
核心思路
通过Hilt注入全局ApplicationContext(而非Activity/Fragment上下文)操作数据库,既满足Repository的需求,又避免内存泄漏——ApplicationContext的生命周期与应用一致,不会随UI组件销毁而失效。同时遵循依赖倒置原则,由Hilt统一管理Repository的实例化,而非在ViewModel中直接创建。
步骤1:配置Hilt基础入口
确保你的Application类添加@HiltAndroidApp注解,这是Hilt初始化的核心入口:
@HiltAndroidApp class MyApplication : Application()
步骤2:修改RepositoryImpl,注入ApplicationContext
在RepositoryImpl的构造函数中,用@ApplicationContext注解注入全局上下文:
interface Repository { fun getData(): Flow<User> } // 用@Inject标记构造函数,让Hilt自动处理依赖注入 class RepositoryImpl @Inject constructor( @ApplicationContext private val appContext: Context ) : Repository { override fun getData(): Flow<User> = flow { // 这里可安全使用appContext操作数据库(比如Room实例化) // 示例:val db = AppDatabase.getInstance(appContext) // 从数据库获取数据并发射 } }
步骤3:绑定Repository接口与实现类
创建Hilt Module,将Repository接口绑定到具体实现类,让Hilt知道如何提供实例:
@Module @InstallIn(SingletonComponent::class) // 绑定到单例组件,保证Repository实例全局唯一 abstract class RepositoryModule { @Binds abstract fun bindRepository(impl: RepositoryImpl): Repository }
步骤4:修改ViewModel,注入Repository
给ViewModel添加@HiltViewModel注解,并通过构造函数注入Repository,禁止手动实例化:
@HiltViewModel class DataViewModel @Inject constructor( private val repository: Repository ) : ViewModel() { private val _user = MutableStateFlow<User?>(null) val user: StateFlow<User?> = _user fun getUser() { viewModelScope.launch { repository.getData().collect { user -> _user.value = user } } } }
关键说明
- 防内存泄漏:
@ApplicationContext注入的是应用级上下文,生命周期与应用绑定,不会因ViewModel或UI组件销毁引发泄漏。 - 低耦合设计:ViewModel依赖Repository接口而非具体实现,后续可轻松替换实现类或编写测试用例。
- Hilt自动管理:所有依赖的实例化由Hilt负责,无需手动创建对象,减少重复代码和人为错误。
内容的提问来源于stack exchange,提问作者Slava
相关产品推荐
相关产品推荐

