Hilt如何注入ViewModel参数?带参Repository注入疑问
问题解答
一、Activity代码无需修改
原Activity的代码完全不需要改动,依然保持如下写法:
@AndroidEntryPoint class ExampleActivity : AppCompatActivity() { private val exampleViewModel: ExampleViewModel by viewModels() ... }
Hilt的依赖注入逻辑是在容器层面完成的,Activity只需要通过by viewModels()获取ViewModel实例即可,无需关心ViewModel依赖的Repository的参数问题。
二、告知Hilt传递Repository参数的几种方式
根据Repository参数的来源不同,有以下几种常见处理方案:
1. 参数为可注入的依赖
如果ExampleRepository的构造参数本身是Hilt能提供的依赖(比如其他被@Inject标注的类、Hilt内置的Context等),直接给Repository的构造函数加上@Inject注解即可:
class ExampleRepository @Inject constructor( private val apiService: ApiService, // 假设ApiService已配置Hilt注入 private val appContext: @ApplicationContext Context ) { // ... }
Hilt会自动从依赖容器中获取对应实例,注入到Repository里。
2. 参数为运行时动态值
如果参数是运行时才能确定的动态值(比如用户ID、自定义配置),需要通过Hilt模块绑定来提供实例:
- 第一步:定义限定符标记该动态参数,避免依赖冲突:
@Qualifier @Retention(AnnotationRetention.BINARY) annotation class UserId
- 第二步:在Hilt模块中提供Repository实例,同时传入动态参数:
@Module @InstallIn(SingletonComponent::class) // 根据需求选择合适的作用域组件 object RepositoryModule { @Provides fun provideExampleRepository( @UserId userId: String, apiService: ApiService ): ExampleRepository { return ExampleRepository(userId, apiService) } // 提供动态参数的实例,示例从SharedPreferences获取用户ID @Provides @UserId fun provideUserId(@ApplicationContext context: Context): String { val prefs = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE) return prefs.getString("user_id", "") ?: "" } }
Hilt创建Repository时会自动调用provideExampleRepository方法,获取所需的动态参数和其他依赖。
3. 参数来自ViewModel的SavedStateHandle
如果参数和ViewModel的状态强绑定(比如来自SavedStateHandle),可以直接在ViewModel中手动创建Repository实例:
@HiltViewModel class ExampleViewModel @Inject constructor( private val savedStateHandle: SavedStateHandle, private val apiService: ApiService ) : ViewModel() { // 从SavedStateHandle中取参数,手动初始化Repository private val exampleRepository = ExampleRepository( savedStateHandle.get<String>("user_id") ?: "", apiService ) ... }
内容的提问来源于stack exchange,提问作者Johann
相关产品推荐
相关产品推荐

