I have been developing for Android for little less then 2 years, and I am still puzzled by this seemingly simple question. When should one implement a service? From my experience there are some rare cases but I am questioning this because on every phone there are quite a lot of them running and I doubt it's just a poor application design.
This is essentially core of my question but following are some of my experiences and thoughts about the subject which can explain my question in more detail.
In all apps that I have developed only one really required a service. It was a background sound recorder and I was using it as Foreground service with notification since I wanted buttons to be able to control it (like music players do for example).
Except this I never really saw a requirement for the constantly running service because:
A) Intent listeners (Manifest registered BroadcastReceivers) are quite a useful feature and using them as you know is usually enough for many use-cases (for example showing notifications).
B) If scheduled execution is a must one can subscribe to alarm events.
C) I know that service in Android is quite different then for example in Windows since in Android services are just a "package" to organize your code in and have a the system manage the lifetime of the object. Services use the Main Thread but it's customary to spawn new threads in them.
D) In the development documentation services are suggested for network communication and background calculations but I don't get why you should not just use AsyncTasks for that. I am a big fan of these and use them extensively for lot of things from downloading data from the internet to doing FFT calculations under time critical conditions.
E) I get the usefulness of Foreground services but why are people using background services so much (excluding the system apps).
Those are my thoughts about the SERVICE and I hope someone with more experience will be able to explain these PROS and CONS (along with others that I probably missed).
When you have work -- delivering value to the user -- that:
Needs some time to complete, perhaps longer than you have time for in the component wishing the work to be done, or
Is delivering that value under user control (e.g., music player, controlled by play/pause buttons in a UI), or
In rare cases, needs to be running continuously, as it delivers value continuously
Some are likely to be poor implementations, either due to technical misunderstandings, or other concerns (e.g., making marketing happy) trumping making users happy.
That is a reasonable use for a service, IMHO.
I assume that by "Intent listeners" you mean manifest-registered
BroadcastReceiver
s. In that case, if the work to be done by theBroadcastReceiver
will take more than a millisecond, that work should be delegated to anIntentService
for completion.onReceive()
is called on the main application thread, and it is not safe for a manifest-registeredBroadcastReceiver
to fork a bare thread, as the process could go away shortly afteronReceive()
returns. However, in these cases, the service is usually short-lived (e.g., do some network I/O and disk I/O, then go away).An
AsyncTask
is a fine solution for background work that is:Requested by the UI (activity or fragment), and
Will take less than a second or so, and
Is non-critical
For example, if you are downloading avatars to show in a
ListView
,AsyncTask
is probably a fine choice, whether you use them directly or use some image-fetching library that uses them internally.Conversely, if the user buys an MP3 through your app, and you need to download that MP3 file, an
AsyncTask
is not a good solution. That could easily take over a second. While the download is going on, the user could switch away from the app (e.g., press HOME). At that point, your process is eligible to be terminated... perhaps before your download is complete. Using anIntentService
to manage the download is a signal to the OS that you are really doing work here, adding value to the user, and so the process will be left alone for a little while.Note that if the background work might take 15+ seconds,
WakefulBroadcastReceiver
or myWakefulIntentService
is probably a good idea, so the device does not fall asleep while you are trying to wrap up this bit of work.If you consider UI and bound services, u would think that both can exist and not be doing anything for certian periods. In such scenarios, your UI can be recreated a lot of times however service does not. And this is where service is important. Lets say you are processing images and then rotate device you want processing to continue while UI is being recreated. You recording a voice and then rotate device. These are one of the places where I find service very important. (Having lot of heavy data processing, interaction with web, that could be few seconds)
I can name some of the Service uses from my experience:
to implement
actually (excluding 5.) they all are working for the whole app duration, they are using some of the other android services, also they manage their state. I suppose one of the important thing here is state management during application life cycle changes.
I prefer to look at AsyncTasks in a same way as Executors (ExecutorService), they should be executed sequentially and for small tasks.
In the android website, you can find a table when to use Service, Thread, or WorkManager (the new API for scheduling jobs, currently in alpha as of this comment posted). https://developer.android.com/guide/background/#table-choose
The website also state that you need to use started service only as last resort. The Android platform may not support started services in the future. Refer to this link https://developer.android.com/topic/performance/scheduling#services