1

我开始使用Koin作为服务定位器/DI,因为它易于实现。我面临一个问题:Evernote Jobscheduler

截至目前,我有以下代码:

class ForceUpdateJob : Job() {
const val TAG: String = "FORCE_UPDATE_JOB_TAG"

 fun scheduleJob() {
//Code
}
override fun onRunJob(params: Params): Result {
//Code
}

在我的 SplashViewModel 上,我将我所有的工作都称为:

 private fun scheduleJobs() {
    if (JobManager.instance().getAllJobRequestsForTag(Sync1.TAG).isEmpty())
        Sync1.scheduleJob()

    if (JobManager.instance().getAllJobRequestsForTag(Sync2.TAG).isEmpty())
        Sync2.scheduleJob()

    if (JobManager.instance().getAllJobRequestsForTag(ForceUpdateJob.TAG).isEmpty())
        ForceUpdateJob.scheduleJob()
}

我有一个这样的工作创造者:

class MyJobCreator : JobCreator {

override fun create(tag: String): Job? = when (tag) {
    Sync1Job.TAG -> Sync1Job()
    Sync2Job.TAG -> Sync2Job()
    ForceUpdateJob.TAG -> ForceUpdateJob()
    else -> null
}
}

在我的 App 类上,我像这样创建 JobManager:

  JobManager.create(this).addJobCreator(MyJobCreator())

它运行良好,我所有的工作都是周期性的,每 15 分钟安排一次,一切都运行良好。(此结构遵循 Jobscheduler github 页面上的说明)

但是当开始使用 DI 和 Koin 时,进行了以下更改:

我的模块包含我需要的所有依赖项:

val forceUpdateModule: Module = module {
bean { ForceUpdateDataSource() as ForceUpdateDataSourceInterface }
bean { ForceUpdateRepository(get()) as ForceUpdateRepositoryInterface }
factory { ForceUpdateWorker(get()) }
factory { ForceUpdateJob(get()) }
}

我的 Repository 单例实例现在由我的 Worker 的依赖项传递,而 Worker 作为我的更新作业的依赖项传递:

class ForceUpdateJob(val forceUpdateWorker: ForceUpdateWorker) : Job() 

class ForceUpdateWorker(val repository: ForceUpdateRepositoryInterface)

所以为了让它工作,我不得不改变我的 JobCreator 类:

class MyJobCreator(private val forceUpdateJob: ForceUpdateJob) : JobCreator

并为此创建一个新模块:

val jobSchedulerModule: Module = applicationContext {
factory { MyJobCreator(get()) }
}

奇怪的部分出现在 AppCoordinator 上,我创建了一个属性并注入它:

所以这:

 JobManager.create(this).addJobCreator(MyJobCreator())

变成了这样:

private val myJobCreator : MyJobCreator by inject()
JobManager.create(this).addJobCreator(myJobCreator)

我像这样开始koin:

private fun initKoin() {
    startKoin(this,
            listOf(forceUpdateModule,
                    splashModule,
                    jobSchedulerModule))
}

这确实是第一次。但是,当作业被重新安排并尝试再次执行时,我的应用程序崩溃并出现以下异常:

标签 FORCE_UPDATE_TAG 的作业已经运行,创建者应始终创建一个新的作业实例

关于我缺少什么的任何想法?

提前致谢

4

1 回答 1

0

我认为您的问题与就业创造者不再创造就业这一事实有关。

作业创建者必须遵循工厂设计模式,每次您要重新安排作业时,都必须创建该作业的新实例。因此,您的 MyJobCreator 应该只接收创建作业所需的依赖项。不是工作本身。

所以我会删除 koin 工作工厂,并让你的 MyJobCreator 接收一个 factoryUpdateWorker,它会有一个这样的 create 方法:

class MyJobCreator(val forceUpdateWorker: ForceUpdateWorker) : JobCreator

    override fun create(tag: String): Job? = when (tag) {
        Sync1Job.TAG -> Sync1Job()
        Sync2Job.TAG -> Sync2Job()
        ForceUpdateJob.TAG -> ForceUpdateJob(forceUpdateWorker)
        else -> null
    }
}
于 2018-12-26T13:36:03.337 回答