You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多模块Android应用(Hilt+Dagger2):Domain模块获取Context提供DataStore问题

解决方案:多模块下Domain模块获取Context提供DataStore的问题

针对你遇到的App用Hilt、Feature用Dagger2的多模块场景,以下是三种可行的解决思路:


方案一:自定义Qualifier传递ApplicationContext

核心思路是绕开Hilt专属注解,通过自定义注解让Hilt提供的Context能被Dagger2模块识别:

  1. 在Domain模块定义自定义Qualifier(避免跨模块依赖Hilt)
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class AppContext
  1. 在App模块的Hilt模块中提供带Qualifier的Context
@Module
@InstallIn(SingletonComponent::class)
class AppModule {
    @Provides
    @AppContext
    fun provideAppContext(@ApplicationContext context: Context): Context {
        return context
    }
}
  1. Domain模块的Dagger模块使用自定义Qualifier注入Context
@Module
class DomainModule {
    @Provides
    @Singleton
    fun provideDataStore(@AppContext context: Context): DataStore<...> = context.dataStore
}
  1. 关联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仅定义抽象接口:

  1. Domain模块定义DataStore抽象接口
interface UserPreferencesStore {
    suspend fun saveUserInfo(info: UserInfo)
    suspend fun getUserInfo(): UserInfo?
}
  1. 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? {
            // 实现读取逻辑
        }
    }
}
  1. Domain/Feature模块直接依赖抽象接口
    无需关心Context来源,通过Dagger/Hilt注入接口实例即可。

方案三:用Hilt替代Dagger2处理多绑定

Hilt完全支持自定义注解的多绑定,可直接替换Feature模块的Dagger2,解决Context依赖问题:

  1. 给Feature模块添加Hilt依赖
implementation "com.google.dagger:hilt-android:2.48"
kapt "com.google.dagger:hilt-android-compiler:2.48"
  1. 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
}
  1. Feature模块使用Hilt组件
    无需再维护Dagger2组件,直接用Hilt的@AndroidEntryPoint等注解完成注入。

内容的提问来源于stack exchange,提问作者onStackOverflowListener

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 20:13:21