androidandroid-servicejob-schedulingwakelockrobospice

Job manager in Android


I have a task to run several different jobs in Android app. Each job is long-running and cosumes network, database and file system much. Each job can be run manually by user or scheduled by AlarmManager. It is very important that each job runs till the end, so it needs to continue running after user leaves the app, or even when user does not open the app at all. Jobs have some ID attribute like this:

class Job {
    int id;
}

I need this hypothetical JobManager to receive jobs and sort them by ID. If a job with id = 1 is already running, then JobManager should skip all the subsequent jobs with id = 1 until this job is finished. But if a job is submitted with id = 2, then it is accepted and can be run in parallel with the first job.

The jobs should also to keep wake lock until completed, like it is done in CommonsWare's WakefulIntentService.

I have several ideas how to implement this, but all have their drawbacks:

  1. Subclass of the Service class that runs always in background and is automatically restarted, when killed for some reason. Drawbacks: it consumes resources even if not running anything, it is running on UI thread, so we have to manage some threads that can be killed by system as usual, each client has to start the Service and nobody knows, when to stop it.
  2. WakefulIntentService from CommonsWare. Drawbacks: because it is IntentService, it runs only sequentially, so it cannot check for existing running job.
  3. Boolean "running" flag in the database for each job. Check it every time we want to run a job. Drawbacks: too many requests to db, difficult to implement properly, sometimes 2 equal jobs still can run in parallel, not sure about flags staying "true" in case of any unexpected error.
  4. Existing library disigned for this purpose. As for now except CWAC-Wakeful I have found:

    but still I don't know, how to use these libraries to run exactly one centralized service, that whould accept jobs from any other Activity, Service, BroadcastReceiver, AlarmManager, etc, sort them by ID and run in parallel.

Please advise me what solution can be used in this case.

UPDATE: See below my own solution. I'm not sure, if it works in all possible cases. If you are aware of any problems that may arise with this, please comment.


Solution

  • This seems to be suited for the new JobScheduler API on Lollipop, then you will have to make a wrapper around it to implement all the features that the sdk implementation is missing.

    There is a compat library if you need to implement this on versions below Lollipop.