多模块Android应用(Hilt+Dagger2):Domain模块获取Context提供DataStore问题
解决方案:多模块下Domain模块获取Context提供DataStore的问题
针对你遇到的App用Hilt、Feature用Dagger2的多模块场景,以下是三种可行的解决思路:
方案一:自定义Qualifier传递ApplicationContext
核心思路是绕开Hilt专属注解,通过自定义注解让Hilt提供的Context能被Dagger2模块识别:
- 在Domain模块定义自定义Qualifier(避免跨模块依赖Hilt)
@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class AppContext
- 在App模块的Hilt模块中提供带Qualifier的Context
@Module @InstallIn(SingletonComponent::class) class AppModule { @Provides @AppContext fun provideAppContext(@ApplicationContext context: Context): Context { return context } }
- Domain模块的Dagger模块使用自定义Qualifier注入Context
@Module class DomainModule { @Provides @Singleton fun provideDataStore(@AppContext context: Context): DataStore<...> = context.dataStore }
- 关联Feature的Dagger组件与Hilt组件
在App模块暴露Hilt组件的接口,让Feature的Dagger组件依赖该接口获取Context:
// App模块定义接口 interface AppComponentProvider { @AppContext fun getAppContext(): Context } // 让Application实现该接口 @HiltAndroidApp class MyApp : Application(), AppComponentProvider { override fun getAppContext(): Context = applicationContext } // Feature模块的Dagger组件依赖该接口 @Component(dependencies = [AppComponentProvider::class]) interface FeatureComponent { // 定义需要注入的类型 } // 在App中构建Feature组件 val featureComponent = DaggerFeatureComponent.builder() .appComponentProvider(this) .build()
方案二:将DataStore提供逻辑移至App模块
把Context相关的实现放在Hilt管辖的App模块,Domain仅定义抽象接口:
- Domain模块定义DataStore抽象接口
interface UserPreferencesStore { suspend fun saveUserInfo(info: UserInfo) suspend fun getUserInfo(): UserInfo? }
- App模块用Hilt实现并提供该接口
@Module @InstallIn(SingletonComponent::class) class AppDataStoreModule { @Provides @Singleton fun provideUserPreferencesStore(@ApplicationContext context: Context): UserPreferencesStore { return UserPreferencesStoreImpl(context.dataStore) } private class UserPreferencesStoreImpl(private val dataStore: DataStore<...>) : UserPreferencesStore { override suspend fun saveUserInfo(info: UserInfo) { // 实现存储逻辑 } override suspend fun getUserInfo(): UserInfo? { // 实现读取逻辑 } } }
- Domain/Feature模块直接依赖抽象接口
无需关心Context来源,通过Dagger/Hilt注入接口实例即可。
方案三:用Hilt替代Dagger2处理多绑定
Hilt完全支持自定义注解的多绑定,可直接替换Feature模块的Dagger2,解决Context依赖问题:
- 给Feature模块添加Hilt依赖
implementation "com.google.dagger:hilt-android:2.48" kapt "com.google.dagger:hilt-android-compiler:2.48"
- Feature模块用Hilt实现多绑定+DataStore提供
// 自定义多绑定Qualifier @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class FeatureServices // 多绑定模块 @Module @InstallIn(SingletonComponent::class) abstract class FeatureMultibindingModule { @Binds @IntoSet @FeatureServices abstract fun bindAuthService(service: AuthService): FeatureService } // DataStore提供模块 @Module @InstallIn(SingletonComponent::class) class FeatureDataStoreModule { @Provides @Singleton fun provideDataStore(@ApplicationContext context: Context): DataStore<...> = context.dataStore }
- Feature模块使用Hilt组件
无需再维护Dagger2组件,直接用Hilt的@AndroidEntryPoint等注解完成注入。
内容的提问来源于stack exchange,提问作者onStackOverflowListener
相关产品推荐
相关产品推荐

