如何用Dagger Hilt为JobService注入Room DAO、Retrofit及选择合适协程Scope
Service依赖注入实现方案
Android系统组件(包括Service、Activity、BroadcastReceiver等)由系统Framework负责实例化,确实不支持构造注入,只能使用字段注入实现依赖传入,需要的Dagger组件配置如下:
- 首先确认你已有提供依赖的基础Module:
RoomModule:标记@Singleton作用域,内部提供Room Database实例、各DAO接口实例RetrofitModule:标记@Singleton作用域,内部提供Retrofit实例、各API接口实例
- 配置注入入口:
如果使用原生Dagger,直接在Application级别的Singleton Component中添加对应JobService的注入方法:
如果使用Dagger Android扩展,只需在AndroidInjector模块中添加服务绑定即可:@Singleton @Component(modules = [RoomModule::class, RetrofitModule::class]) interface AppComponent { fun inject(service: MySyncJobService) }@Module abstract class ServiceBuilderModule { @ContributesAndroidInjector abstract fun bindMySyncJobService(): MySyncJobService } - 触发注入:
原生Dagger需要在JobService的onCreate生命周期中手动触发注入:
Dagger Android环境下直接让JobService继承class MySyncJobService : JobService() { @Inject lateinit var userDao: UserDao @Inject lateinit var userApi: UserApi override fun onCreate() { super.onCreate() (application as MyApp).appComponent.inject(this) } }DaggerJobService即可,无需手动编写注入逻辑。
Service访问Room的协程Scope选择
优先使用AndroidX Service扩展提供的lifecycleScope,该Scope和Service的生命周期绑定,会在Service销毁时自动取消所有未完成的协程任务,避免内存泄漏。
示例调用逻辑:
override fun onStartJob(params: JobParameters?): Boolean { lifecycleScope.launch(Dispatchers.IO) { // 读取本地待同步数据 val pendingData = userDao.getPendingSyncData() pendingData.forEach { data -> runCatching { userApi.uploadSyncData(data) } .onSuccess { userDao.markSynced(data.id) } .onFailure { /* 记录失败状态,等待下次调度重试 */ } } // 任务执行完成通知系统 jobFinished(params, false) } // 返回true表示存在异步任务需执行 return true }
注意:非必要不要使用GlobalScope,会导致任务不受组件生命周期管理,极易引发内存泄漏。
Retrofit实例注入配置
Retrofit API实例的注入逻辑和DAO完全一致,只要在你的Retrofit Module中声明对应API接口的提供方法,就可以直接在JobService中通过@Inject字段获取实例:
@Module class RetrofitModule { @Provides @Singleton fun provideRetrofit(): Retrofit { return Retrofit.Builder() .baseUrl("https://your-api-domain.com/") .addConverterFactory(GsonConverterFactory.create()) .build() } @Provides @Singleton fun provideUserApi(retrofit: Retrofit): UserApi { return retrofit.create(UserApi::class.java) } }
内容的提问来源于stack exchange,提问作者Diken Mhrz
相关产品推荐
相关产品推荐

