IntentService + startForeground vs JobIntentService - android

Since Android Oreo background execution limits, the docs recommend to refactor IntentServices to JobIntentService.
https://developer.android.com/about/versions/oreo/background
JobIntentService runs immediately as an IntentService below Oreo, but schedules a Job on Oreo+
https://developer.android.com/reference/android/support/v4/app/JobIntentService
In what cases would it make sense to run a normal IntentService as a foreground Service with a persistent notification, and when is a JobIntentService better?
One downside I can see in JobIntentService is that it doesn't start immediately.

Foreground service is not affected by Doze, but you still have to use wake locks, if you need your task to be continued when the screen is off.
The JobIntentService (which uses the JobScheduler) manages wake locks for you, but you have less control when the job will be started.
I would use the foreground IntentService (or Service) for high priority tasks (e.g. downloading a database) that should run immediatelly and that should not be paused / killed by system.
I would use the JobIntentService in conjunction with AlarmManager to schedule low priority tasks like refreshing the widget's data periodically.

If you want to make long running operation something like Music Player use Foreground Service with notification. because JobIntentService has time execution limit like JobScheduler. ( 10 minutes)
If you think that user don't need to know about your work you can use JobIntentService without notification.
You don't need to worry about Doze mode if user is actively using your app.
There are some cases for Doze mode, according to https://www.bignerdranch.com/blog/diving-into-doze-mode-for-developers/
Light-Doze starts to kick in shortly after both the screen is off and
the device is not charging, waiting only a couple minutes before
applying the restrictions just to make sure the user has stopped using
their phone
For example, user turned screen off while you are computing something. Your task is finished and you want to run background service. In that case your JobIntentService can be deffered, because device can be in doze mode.
However, if you want immediately perform background operation use ForegrounService with WakeLock, because ForegroundService is not working when the screen is off.

Related

Difference between Foreground Service and JobScheduler

I have an app where I use a foreground service to start a number N of threads that sleep most of the time and sometimes wake up to do some measurements.
I used foreground services because I need that these measurements must be done at specific and exact time without background limitations introduced by Android 8.0.
This seems to work and from documentation seems that there are no problem, but I read also about JobScheduler.
There is an advantage to use Jobs to schedule work at specific accurate time or my solution can be used without problems.
First a fact
In JobScheduler, the System execute your Job(Task) in application's JobService
and the JobService class also extend the same Service class that we use to define Foreground Service. So by using the both, we can execute code in background
Now the main difference is, Foreground Service is always running(by showing notification to user) and consuming the battery and memory of the user even, if your threads are sleeping and no code is executing.
As it's running always you can do whatever you want precisely at any moment of time. maybe it's good for your app's point of view but it's bad for user. your app draining the battery unnecessarily and consuming the RAM.
To address this problem we got JobScheduler. you can Schedule a job to be executed based on some criteria. Your app will only wake when the criteria is met, but it's not precise.it depends on many factors like doze mode etc.
you can look more about that here
The conclusion is
If your task is not needed to be execute at exact time then you should use JobScheduler (recently WorkManager is better as it use JobScheduler internally and more advance) to save your user's battery
and according official document
WorkManager is intended for tasks that are deferrable—that is, not
required to run immediately—and required to run reliably even if the
app exits or the device restarts.
For your use case, you will be better off using a WorkManager which according to the android documentation, uses JobScheduler on API 23+ and a combination of BroadcastManager and AlarmManager on API 14 - 22.
With a WorkManager your jobs will run reliably even if your app exits or the device restarts.
https://developer.android.com/topic/libraries/architecture/workmanager

background task questions

I have been reading lately about how background jobs are done in Android (using Service, AlarmManager, JobScheduler, etc) and learned that these background task can go indefinitely even the app has already closed or device has screened off. I understand that the only they stop if they stop themselves or other components stop them.
Questions:
If I have a background job or an alarm that goes every 1 hour. Does it really runs forever until a component stop them? Is there an instance that the system will stop them?
What if I have periodic job or alarm that goes every 1 hour. Will they stop if I uninstall the app that started them? Cos I never read this part in any documentation.
Is there a way to check any running or pending background jobs/alarms in my device?
The explanation that is given about background tasks in your question only applies to Background Services, that to only in Android API Levels below 26.
Google recommends using JobScheduler or Foreground Service to do some work in background even when app is not in foreground.
Coming to you questions
No, If your using JobScheduler or Alarm manager the system will trigger your job to do your work depending on device idleness and conditions mentioned by you but the system can anytime come and stop your work in between when the conditions are no longer met.
If your are using JobScheduler it will inform you when system wants to stop by force so that you can handle it properly and reschedule if needed
When the App is uninstalled every job or alarm that is scheduled or in-Progress will be destroyed.
Yes, JobScheduler does provide a function 'getAllPendingJobs'
Note :
For works that should be scheduled or completed even when app is closed then try avoiding the use of Background Services or Alarm Managers.
JobScheduler is much more better replacement.
If you want to do some simple background work when the app is in foreground then try using HandlerThreads or AsyncTasks

Scheduling JobService to run only when app is running (on foreground)

I need to do some background updates (about every 1 min). I have to use JobService to do it periodically. But I don't need to run service when app is closed - only when app is running (on foreground).
Is there is a way to do that?
You don't need a JobService for that. Simply use normal Service. The OS allows apps in foreground to freely create the service. You can easily start a Service and perform your task. You can use Handlerthread for background processing or use Handler for foreground processing.
Note for Android O: If your app goes to background then your Service will be stopped as if you have called stopSelf(). Remember to clean up the necessary object's state.

What performance gains Job Scheduler gives over startService()

From Oreo, a service will not work if the app is not in foreground, but we can use JobSchedular to perform background operations.
Then what's really is the difference between JobScheduler and startService(), and why android is supporting JobSchedular over startService() for background operations from oreo.
I can still Schedule tons of Jobs from backround, and it will also effect battery performance.
From Oreo, a service will not work if the app is not in foreground
Yes, it will. It merely needs to be a foreground service.
Then what's really is the difference between JobScheduler and startService()
startService() is immediate. A job scheduled with JobScheduler is not. JobScheduler can postpone the work until a later time, when other work needs to be done, to minimize the amount of time that power is consumed (for CPU, for WiFi, for mobile data, etc.).
Also, startService() always happens. A job scheduled with JobScheduler might not. You can put criteria on the job (e.g., requires a network connection), and the job will only be run if the criteria are met.
and why android is supporting JobSchedular over startService() for background operations from oreo.
Power consumption, mostly, as far as I can tell.
I can still Schedule tons of Jobs from backround, and it will also effect battery performance.
Yes, but Google has a much better API for being able to control that in the future. If developers abuse JobScheduler, future versions of Android can further rate-limit jobs, expand Doze mode for jobs, and so on.
From Android developers website:
The framework will be intelligent about when it executes jobs, and
attempt to batch and defer them as much as possible. Typically if you
don't specify a deadline on a job, it can be run at any moment
depending on the current state of the JobScheduler's internal queue.
While a job is running, the system holds a wakelock on behalf of your
app. For this reason, you do not need to take any action to guarantee
that the device stays awake for the duration of the job.
When you start a background service it is running even if the app is in the background, thus it uses resources. With JobScheduler the resources are only allocated and used for a particular job, and are freed when it's done.

Keep my IntentService alive when phone is off

My IntentService checks the user's location. I need to keep it alive while the phone is turned off. In this Service I have an infinite while loop. The OS will shut it down after 8 minutes.
What other ways can I do this instead of the AlarmManager?
IntentService is supposed to be executed once. When job is done, it terminates. You may try using ordinary Service and do all work on background thread. But, system can stop this service anyway if it is low on resources. To prevent that, you can use .setForeground() method in Service and Service will not be stopped by system. But, there will be icon in notification tray.

Categories

Resources