Hilt框架下能否跨模块注入单例自定义对象?MyPreference在NetworkModule中未初始化的求助
我帮你找到问题根源了——你在NetworkModule里用@Inject lateinit var myPreference: MyPreference的方式是错误的!Hilt的模块类(带@Module注解的类)的职责是提供依赖实例,而不是作为依赖注入的接收方,所以Hilt不会自动初始化模块里的成员变量,这就是为什么你的myPreference始终未初始化。
正确的解决步骤
移除NetworkModule里的@Inject成员变量
删掉NetworkModule中那行@Inject lateinit var myPreference: MyPreference,模块里不需要这种写法。在@Provides方法中通过参数获取MyPreference
当你需要在创建Retrofit/OkHttpClient时用到MyPreference,直接把它作为@Provides方法的参数即可——Hilt会自动解析并注入这个依赖实例,前提是你已经正确配置了MyPreference的提供逻辑。确认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

