Hilt中能否复用同一provide方法动态返回不同Retrofit服务实例
结论
你设想的「单个@Provides函数运行时根据用户操作动态返回不同类型APIService实例」的方案无法实现,核心原因和替代方案如下:
核心原因
Hilt是静态依赖注入框架,所有依赖绑定关系在编译阶段就会完成校验和固定,根本不支持运行时动态修改提供逻辑:
- 你写的
provideRetrofitService方法返回值固定写死为UserAPIService,Hilt只会在依赖图中注册UserAPIService类型的绑定,根本不会识别其他APIService类型,编译阶段就会把类型不匹配的注入请求判定为错误。 - 你给方法加了
@Singleton注解,对应实例会在首次被依赖请求时创建,生命周期和应用进程绑定,后续不会再重新执行提供方法,完全没法响应运行时的用户点击操作来切换实例。 - 就算你强行把方法返回值改成通用父类/Any类型,Hilt也无法根据调用方的需求自动匹配返回对应子类实例,注入时会直接抛出类型不匹配的运行时异常。
可落地的替代方案
完全没必要硬磕单个provide方法实现动态返回,行业里常规的实现方式有两种,都适配你当前的Activity/Fragment - ViewModel - Repo - RemoteDataSource分层架构:
方案1:为每个APIService单独声明提供方法
Retrofit的create方法本身有内部实例缓存,就算为每个Service单独写@Provides方法,也不会有额外的性能开销,是最符合Hilt设计规范的写法:
@Provides @Singleton fun provideUserAPIService(retrofit: Retrofit): UserAPIService = retrofit.create(UserAPIService::class.java) @Provides @Singleton fun provideProductAPIService(retrofit: Retrofit): ProductAPIService = retrofit.create(ProductAPIService::class.java)
后续在Repo或者RemoteDataSource层按需注入对应的Service实例即可。
方案2:直接注入Retrofit实例,按需创建服务
如果觉得给每个Service写提供方法太繁琐,可以直接把Retrofit实例注入到数据层,在需要使用对应服务的时候再调用create方法获取,Retrofit内部的缓存机制会保证同一个Service只会创建一次实例,不会重复生成对象:
class RemoteDataSource @Inject constructor( private val retrofit: Retrofit ) { private val userApi by lazy { retrofit.create(UserAPIService::class.java) } private val productApi by lazy { retrofit.create(ProductAPIService::class.java) } // 业务逻辑按需调用对应服务的接口即可 suspend fun getReviewData(customerId: String): Response<ReviewResponse> { return userApi.getReviewData(customerId) } }
内容的提问来源于stack exchange,提问作者Shyneil Singh
相关产品推荐
相关产品推荐

