我正在尝试更新我的简单安卓应用程序以使用Dagger2。我想我已经设法理解了一些基础知识,并且通过它创建了基本的东西(活动、视图模型、助手(。
现在,仍然有一个小问题:该应用程序有一个按钮,按下该按钮时,必须安排工作服务。我可以重构我的 jobservice,以便它的依赖项通过其构造函数传递,但是如何从我的活动中实例化它?换句话说,如何替换此代码:
val serviceComponent = ComponentName(getApplication(), DbUpdaterJob::class.java)
var jobInfo = JobInfo.Builder(DB_UPDATER_JOB_ID, serviceComponent)
.setRequiredNetworkType(networkType)
.setPersisted(true)
.build()
val scheduler = getApplication<Application>().getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
val res = scheduler.schedule(jobInfo)
所以实例化被降级为dagger?
谢谢!
经过一番挖掘,它最终比我想象的要容易......因此,我为作业绑定创建了一个新模块:
@Module
abstract class JobBindingModule {
@ServiceScoped
@ContributesAndroidInjector
internal abstract fun provideDbUpdatedJob(): DbUpdaterJob
}
顺便说一句,ServiceScoped 是一个新的注释,如下所示:
@Scope
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE, ElementType.METHOD)
annotation class ServiceScoped
我已将该模块添加到我的dagger组件模块集合中。之后,我将构造函数参数注入替换为属性注入:
class DbUpdaterJob: JobService() {
@Inject
lateinit var dbManager: NewsManager
最后,我重写了注入所需依赖项的onCreate
方法:
override fun onCreate() {
super.onCreate()
AndroidInjection.inject(this)
}
它似乎正在工作...
您需要定义提供程序:
@Provides
fun provideServiceComponent(app: Application): ComponentName =
ComponentName(app, DbUpdaterJob::class.java) // assuming you have only one ServiceComponent
@Provides
fun provideJobInfo(
serviceComponent: ComponentName
): JobInfo =
JobInfo.Builder(DB_UPDATER_JOB_ID)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE)
.setPersisted(true)
.build()
@Provides
@Singleton
fun provideJobScheduler(app: Application): JobScheduler = app.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
然后注入
@Inject constructor(
jobInfo: JobInfo,
scheduler: JobScheduler
) {
val res = scheduler.schedule(jobInfo)
...
}
如果您希望能够创建不同的组件名称或作业信息等,它会变得更加复杂。在这种情况下,您需要使用@Named注射。