this question is just to get some ideas on these concepts to see what people in the industry use these for.
If you can just give a few example uses for each of these, I would greatly appreciate it. I know how they work and did read the google documentation on them but I still seem to be having a hard time picking one over the other. I don't need you to explain to me how they work. I am simply asking for a few of their example uses. How you ended up incorporating them into your apps and why you picked them over the others.
Thanks
AlarmManager
Using the AlarmManager to Schedule Tasks at the System Level
The AlarmManager provides access to system-level alarm services. Using the AlarmManager allows an application to schedule tasks that may need to run or repeat beyond the scope of its lifecycle. This allows the application to perform some function even after the application process or all of its Android components have been cleaned up by the system.
Typically, the AlarmManager is used to fire off a PendingIntent that will start up a Service in the future. The AlarmManager triggers Services based on an elapsed interval or at a specific clock time. Both of these options also have the ability to wake up the device when it is asleep if the alarm is urgent.
The benefits of the AlarmManager come into play when using inexact intervals or times to fire off Services. The Android system tries to batch alarms with similar intervals or times together in order to preserve battery life. By batching alarms from multiple applications, the system can avoid frequent device wake and networking.
One concern to consider while using the AlarmManager is that alarms are wiped out during device reboots. Applications need to register the RECEIVE_BOOT_COMPLETE permission in their Android Manifest and reschedule their alarms in a BroadcastReceiver.
Another concern is that a poorly designed alarm could cause battery drain. While the AlarmManager does have the ability to wake devices and set an exact time for an alarm, the documentation mentions that developers should be wary of these features when performing networking. Aside from draining a device’s battery by avoiding batch alarms, setting an exact time for an application to sync with a server could put high strain on a server if every application installation tries to sync with the server around the same time! This can be avoided by adding some randomness to alarm intervals or times.
AlarmManager is a great candidate for scheduling if an application needs to perform a local event at an exact time or inexact interval. Alarm clock or reminder applications are great examples for AlarmManager usage. However, the documentation discourages using AlarmManager for scheduling network-related tasks. Let’s take a look at some better options for networking.
Job Scheduler
JobScheduler helps perform background work in an efficient way, especially networking. JobServices are scheduled to run based on criteria declared in JobInfo.Builder(). These criteria include performing the JobService only when the device is charging, idle, connected to a network or connected to an unmetered network. JobInfo can also include minimum delays and certain deadlines for performing the JobService. Jobs will queue up in the system to be performed at a later time if none of these criteria are met. The system will also try to batch these jobs together in the same manner that alarms are scheduled in order to save battery life when making a network connection.
Developers might be concerned about a scheduler that frequently delays firing off its JobServices. If jobs are frequently delayed and data stale as a result, it would be nice to know about such things. JobScheduler will return information about the JobService such as if it was rescheduled or failed. JobScheduler has back-off and retry logic for handling these scenarios, or developers could handle those scenarios themselves.
Subclassing JobService requires an override of its onStartJob(JobParams params) and onStopJob(JobParams params) methods. onStartJob() is where callback logic for jobs should be placed, and it runs on the main thread. Developers are responsible for threading when dealing with long running jobs. Return true to onStartJob() if separate thread processing needs to occur, or false if processing can occur on the main thread and there is no more work to be done for this job. Developers must also call jobFinished(JobParameters params, boolean needsReschedule) when the job is complete and determine whether or not to reschedule more jobs. onStopJob() will get called to stop or cleanup tasks when initial JobInfo parameters are no longer met, such as a user unplugging their device if that parameter is a requirement.
There might be a lot to think about when implementing a JobService, but it comes with a lot more flexibility than AlarmManager. Another handy feature is that scheduled jobs persist through system reboots.
There is at least one drawback to using JobScheduler. As of the writing of this post, it’s compatable only with API level 21 and higher. Here you can find the distribution of Android devices running various API levels. While there is technically no backport of JobScheduler, a similar tool is GCM Network Manager.
REFERENCE LINK
Related
I'm having trouble deciding whether to run some recurring background work with Alarm Manager or Work Manager:
The work is going to consist of Room Database operations so I'll need access to Dao to complete my work.
It is going to be recurring at fixed intervals (hourly, daily, weekly, monthly, etc.)
I need to set a start date and time for the recurrence intervals.
the work will recur until canceled by the user
If the user is using the app when the work is supposed to be scheduled, I want the work to be done immediately. If the user is not on the app (app is in the background or device is turned off), I don't care if the work is done after the scheduled time as long as it is at least started by the next time the user opens the app.
the work needs to continue as scheduled after device reboots and app restarts.
For recurring background work, AlarmManger isn't suitable. As the name implies, it's intended to notify the system of an event at a precise time. Just like a physical alarm that wakes a person up even if the person sleeps, AlarmManager will wake up the device from doze mode which will result in more power usage. it is suitable for suitations like setting remainders such as for calender events which the users probably set by themselves.
On the other hand, WorkManager is intended to carry out background processing or work that would persist. Workmanager is much more efficient for recurring task especially as it allows you set constraints to determine when it should start or stop the background work.
check the link form the offical documentation on WorkManger:
workmanager architecture
tabular comparison between the two
It mostly depends on how important your task is.
https://developer.android.com/guide/background is a really good entry point to help you choose what you should work with.
WorkManager is the modern, universal approach of handling background work and it fits for most use-cases, it automatically reschedules work after a device restart or an application crash, and it is very efficient in terms of battery usage.
As WorkManager does respect Android's doze mode, it does not guarantee, that the work will be done exactly on time, though it does guarantee, that your work will be done within a certain time frame.
On the other hand, AlarmManager is capable of running work precisely on time. But this means that the device will wake up when your work scheduled with AlarmManager is coming due. This will drain battery and your app will probably show up as battery-draining in the Device Health board.
But as stated in the article above, prefer using WorkManager if possible. AlarmManager should only be used for e.g. a time-sensitive calendar notification.
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
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.
Recently, I'm working on an app that needs to run a Service every day at a certain time.
To do this, I use AlarmManager.
My question is: After activating the AlarmManager (from the Service), can I destroy the Service, and the AlarmManager will still call me in time?
If not, is there any way at a certain time to send me BroadcastRecerver, without running a Service all the time in OS?
Would appreciate help
The short answer to your question: service can still be started from the alarm manager anytime the alarm receiver is able to run. The long answer: usually it's good practice trying to use job schedulers though. They can both decide a better time to run, while ensuring you have the necessary resources to run successfully, such as network or high battery among other criteria.
Alarm managers are only reasonably reliable before Nougat. It's been long announced that developers should stop using it, and start using job schedulers for most use cases. They are meant to replace both the alarm setup and receiver, and allow the phone to save more battery by putting the phone in doze mode for longer and waking up and doing multiple tasks all at once.
Even if you get alarm manager working on your particular phone google makes less and less reliable with each OS release. There are very specific cases where alarms are still the way to go, but unless you're certain to be in one of these try to use job schedulers for all devices running lollipop and later. You can still use alarm manager reliably for kitkat and older, where job schedulers don't exist. More details on: https://developer.android.com/training/monitoring-device-state/doze-standby.html
In either case I think you need to listen for phone's boot so you can register your alarm/job scheduler:
https://developer.android.com/training/scheduling/alarms.html
Job scheduler info:
https://developer.android.com/topic/performance/scheduling.html
For reliability issues: Android AlarmManager not working on some devices when the app is closed
In my Android app I need to do some work every time the user plugs their device. For this purpose right now I use a BroadcastReceiver, which starts my IntentService to do the work when the user plugs the device and stops it when the device becomes unplugged.
Right now I'm thinking of using JobScheduler for Android 5.0+, but what I'm seeing is that with JobScheduler, I would have to schedule my job within the app, by calling
JobScheduler.schedule(JobInfo);
But this is a problem to me, because I want my job to run every time the user connects their device to the charger, even without the user having to open my app.
For this reason, I think one way would be to schedule it the first time the user opens the app, and then always force reschedule, since I cannot trust on the user opening my app every day (which, due to the nature of my app, certainly won't happen).
So, should I stick with BroadcastReceiver or use JobScheduler for Android 5.0+?
And in the case of using JobScheduler, should I schedule my job only once and then always return true in order to force rescheduling?
Thank you.
So, should I stick with BroadcastReceiver or use JobScheduler for Android 5.0+?
Use JobScheduler, this can improve your app’s performance, along with aspects of system health such as battery life. Also, JobScheduler persists through device reboots and supports batch scheduling by which the android system can combine pending jobs thus reducing battery usage. Moreover, you can do distinguish between android versions thus using JobScheduler on Lollipop and up, and AlarmManager on older versions.
And in the case of using JobScheduler, should I schedule my job only once and then always return true in order to force rescheduling?
Now, there are 2 ways to do this :
As you guessed, scheduling your job only once and always returning true in jobFinished() - this should do the trick.
Upon completing a job (originally scheduled by you by calling JobScheduler.schedule(JobInfo)), you schedule another job by calling the same. This will schedule consequent jobs once each job is about to be completed.
Jobscheduler runs in the background and persists through reboots so you should be fine.