creating a reactive JobService

Viewed 500

I'm creating a JobService with Firebase JobDispatcher (very similar to the regular JobService) to run in the background and check if data on a server has changed (I can not use push notifications because I don't own the server).

I'm wondering if the JobService could be made reactive with the help of a subject: Basically I inject a singleton data repository into my app class that launches the JobService, which in turn emits the new data through a subject that can be subscribed to in the app class:

@Inject class DataRepo {
     internal val subject = PublishSubject.create<Data>()

     // the service should only be started when there are actually subscribers observing the subject
     val latestData: Observable<Data> = subject
             .doOnSubscribe { jobDispatcher.create(job) }
             .doOnDispose { jobDispatcher.cancel(job.tag) }
             .share()

     val job = JobDispatcher.newJobBuilder()......build()
}

class LoadDataService : JobService() {
    @Inject
    protected lateinit var dataRepo: DataRepo

    private var networkRequest: Disposable? = null

    override fun onCreate() {
        super.onCreate()
        component.inject(this)
    }

    override fun onStartJob(jobParams: JobParameters): Boolean {
        networkRequest = dataRepo.getNewestData()
                .subscribe({ newData ->
                    dataRepo.subject.onNext(newData)
                    jobFinished(jobParams, false)
                }, { error ->
                    jobFinished(jobParams, true)
                })

        // job hasn't finished yet. Work is still going on in the background
        return true
    }

    override fun onStopJob(params: JobParameters?): Boolean {
        networkRequest?.dispose()
        // job was cancelled before jobFinished could be called.
        // The job should be retried if possible
        return true
    }
}

class App {
    @Inject val dataRepo: DataRepo

    override fun onCreate() {
        dataRepo.latestData.subscribe(this::sendNotification)
    }
}

the problem is that first of all, my emissions never reach the subscriber in the App class, and second there is no guarantee that the device will be awake long enough for all subscribers to finish their work because the system may release the wake-lock after the JobService has called jobFinished().

0 Answers
Related