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

Hilt框架下能否跨模块注入单例自定义对象?MyPreference在NetworkModule中未初始化的求助

解决Hilt中NetworkModule里MyPreference未初始化的问题

我帮你找到问题根源了——你在NetworkModule里用@Inject lateinit var myPreference: MyPreference的方式是错误的!Hilt的模块类(带@Module注解的类)的职责是提供依赖实例,而不是作为依赖注入的接收方,所以Hilt不会自动初始化模块里的成员变量,这就是为什么你的myPreference始终未初始化。

正确的解决步骤

  1. 移除NetworkModule里的@Inject成员变量
    删掉NetworkModule中那行@Inject lateinit var myPreference: MyPreference,模块里不需要这种写法。

  2. 在@Provides方法中通过参数获取MyPreference
    当你需要在创建Retrofit/OkHttpClient时用到MyPreference,直接把它作为@Provides方法的参数即可——Hilt会自动解析并注入这个依赖实例,前提是你已经正确配置了MyPreference的提供逻辑。

  3. 确认MyPreference的依赖配置(可选优化)
    你的MyPreference已经用@Inject构造函数,并且参数@ApplicationContext Context是Hilt可以自动提供的,再加上你给类加了@Singleton注解,其实你可以删掉SharedPrefModule的@Provides方法——Hilt会自动创建MyPreference的单例实例,不需要手动写提供逻辑。当然如果你想保留SharedPrefModule也没问题,两者不冲突(Hilt会优先使用@Provides方法,但这里逻辑一致)。

修改后的代码示例

MyPreference类(保留原逻辑)

@Singleton
class MyPreference @Inject constructor(@ApplicationContext context: Context) {
    private val prefs: SharedPreferences = context.getSharedPreferences(context.getString(R.string.app_name), Context.MODE_PRIVATE)
    
    fun getStoredTag(): String? = prefs.getString("TOKEN", "")
    
    fun setStoredTag(token: String) {
        prefs.edit().putString("TOKEN", token).apply()
    }
}

修改后的NetworkModule

@Module
@InstallIn(SingletonComponent::class)
class NetworkModule {

    // 这里以创建OkHttpClient为例,把MyPreference作为参数传入
    @Provides
    @Singleton
    fun provideOkHttpClient(myPreference: MyPreference): OkHttpClient {
        return OkHttpClient.Builder()
            // 在这里使用myPreference获取token
            .addInterceptor { chain ->
                val token = myPreference.getStoredTag().orEmpty()
                val request = chain.request()
                    .newBuilder()
                    .addHeader("Authorization", "Bearer $token")
                    .build()
                chain.proceed(request)
            }
            .build()
    }

    @Provides
    @Singleton
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .baseUrl("你的API基础地址")
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
}

可选:删除SharedPrefModule(因为Hilt可以自动处理MyPreference的实例创建)

如果你删掉SharedPrefModule,Hilt依然能正常提供MyPreference的单例,因为类本身的@Inject构造函数已经满足依赖注入的要求。

为什么这样可行?

Hilt的依赖注入逻辑是:当@Provides方法需要某个参数时,它会自动查找该参数对应的依赖提供者——不管是通过@Inject构造函数,还是其他@Provides方法,只要依赖是在同一个组件(这里是SingletonComponent)中提供的,就能自动注入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 15:17:29