Android - High frequency background task - android

I need to implement a background task that needs to update the UI about every 10 seconds. I tried the following approaches, but most of them failed.
1) AlarmManager
I started an intent service via AlarmManager. It seems that AlarmManager is only suitable for very low frequencies, like several hours. If I set it to 10 seconds, then the UI does not respond anymore. Why is that? Doesn't the intent service run in a separate thread?
2) IntentService with infinite loop and Thread.sleep
App was terminated after about 30 seconds, UI was not responding at all. Is intent service only for very short background tasks? I found contradicting information about this. Why is the UI not responding although intent service should run in a separate thread?
3) AsyncTask
When using AsyncTask, the UI remains responsive. But for some reasons, no other AsyncTask is started from the UI. I heard about some limits of concurrend AsyncTasks, but 2 should not be too much?
4) Own Threads
That worked. Background service and UI are fully functional. However, I read that it is bad practise to use threads directly when updating the UI. What would be the best way in this context to send data to the Activity?
What do you recommend for a background task that needs to update the UI and reoccures about every 10 seconds?
Best regards!

Since you need the task to happen in recurring fashion, i would think Alarm Manager is better option.
These are my reasons.
It allows you to fire Intents at set times and/or intervals.
We can use them in conjunction with broadcast receivers to start services and perform other operations even when your app is not running, and even if the device itself is asleep.
They help you to minimize your app's resource requirements. You can schedule operations without relying on timers or continuously running background services.
As per android documentation,
For timing operations that are guaranteed to occur during the lifetime
of your application, instead consider using the Handler class in
conjunction with Timer and Thread. This approach gives Android better
control over system resources.

Related

Long running background task, Android

I am parsing all text messages from the device and extracting words from them. For doing this I first used Service, but the issue with it was that it made application slower or sometimes I got notification that Application is taking longer to run.
Alternative to this I used IntentService. But problem with intent service is that whenever I stopped the application, I couldn't see my service running anymore. Alongside I also have to use Alarm Manager to schedule the things.
I am planning to use SyncAdapter for doing both of the things, but I don't think it would be a good option to use it. It would be really helpful if there is a better possible for doing this.
Background task might take upto 5-10 minutes for completion and I am planning to run it in every 12 hours. Though I won't be parsing old messages again. So it won't take longer after first time. The task should not end even when application is closed.
Basically IntentService is apt for background tasks which are not tied to the application lifecycle.
But problem with intent service is that whenever I stopped the
application, I couldn't see my service running anymore.
You can send updates to UI from intent service by using:
LocalBroadcastManager: how to use LocalBroadcastManager?
Handler: How to Collect info from IntentService and Update Android UI
Also you might want to see this video: The Zen of IntentService. (Android Performance Patterns)
EDIT:
Forget about using IntentService, it stops as the app stops because it runs on the same process as the app.
Since you want your service to work as a job every 12 hours, you could use a 'Scheduled Service'.
You can use JobScheduler or Firebase JobDispatcher API

How can I create a never ending IntentService?

I use a service to continuously synchronize information to display on the activity. The service runs an endless loop while(true) in which the information is updated every 10 seconds. In some devices the service stops after a time of execution. How I can keep the task of the intentService running? It must run even if the user minimize the application.
You shoudn't do that (and you even can't since android 6.0: doze). Consider using cloud messaging to notify your app that something has changed on the server.
A Service is ideal for hosting long-running processes that outlive any one activity. If you're just displaying the data, as opposed to saving it or doing some kind of background processing with it, there's no reason to use a Service at all. Just use Handler#postDelayed(...) in the activity, and make sure the task is removed on pause.
Polling every ten seconds is probably excessive. In fact, polling at all is probably inefficient, unless you expect the data to change as frequently as you are polling.

Repeating IntentService using Timers- is it advisable?

I have an IntentService that downloads data from a server and I would like the IntentService to check for server updates at a certain interval. The following posts however advice against repeating a Service using a Timer - and instead emphasize on using an AlarmManager:
Why doesn't my Service work in Android? (I just want to log something ever 5 seconds)
Android - Service: Repeats only once
Android service stops
From Android's reference manual, an IntentService is described as:
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.
The part I don't really understand is why an IntentService (the posts have questions that are directed towards a Service and not an IntentService) is not allowed to execute repetitively using a Timer as it creates its own worker thread for execution. Is it permissible to use a Timer within an IntentService ? Or are AlarmManagers the only solution to periodically execute an IntentService ?
An explanation to this would be most appreciated .
Or are AlarmManagers the only solution to periodically execute an IntentService ?
If you want it to work reliably, yes. Using AlarmManager is also much more friendly to the user.
First, do not have a Service of any form running except when it is actively delivering value to the user. Watching the clock tick is not actively delivering value to the user. Having a Service running gives your process a bit higher priority than other processes, in terms of what processes get terminated to free up system RAM for future work. Having a Service around unnecessarily -- such as simply watching the clock tick -- hampers the user's ability to multitask well, as you tie up system RAM unnecessarily.
This behavior will cause some users to attack you with task killers, such as swiping your app off the recent-tasks list. This will terminate your process, and therefore your Timer goes away too. Similarly, because too many sloppy developers keep their Service around for a long time, Android will automatically terminate such processes after some time, Service notwithstanding.
Finally, usually one facet of "check for server updates at a certain interval" is that you want this work to occur even if the device goes into sleep mode. With your everlasting-service approach, that will require you to keep the CPU on all the time, using a WakeLock. This will significantly impact the user's battery, causing your app to appear on the Settings app's "battery blame screen". That, in combination with the tying-up-system-RAM "feature", will likely incite some poor ratings for your app.
Instead, by using AlarmManager:
Your IntentService only needs to be running while it is doing its work ("check the server updates"), going away in between these events, so your process can be terminated to free up system RAM for other things that the user is doing
By use of the WakefulBroadcastReceiver or WakefulIntentService patterns, you can wake up the device briefly to do this work, then let the device go back to sleep again, thereby minimizing the impact on the battery

Android Services and UI update

I started learning android i've been playing with it and so far so good but i have some doubts about Services, i started learning them today so by gently if a say something very wrong.
For example, i want my app to grab some information over the internet from time to time, this polling period is defined by the user, then the UI gets updated. I though about creating a Service that run lets says every 30 minutes, gets the information and updates the UI.
If i get it right:
An IntentService just executes an operation and stops by itself sending the result through an intent(right?), so i think it's not what i want.
A Bounded Service is most likely used when you want IPC or allow binding from external apps, which again i think it's not what i want.
I think a Local Service is probably what i need, using a LocalBroadcastReceiver to update the UI, how can i make it to run the operation every X minutes( Handler postDelayed, ScheduledExecutorService or Alarm Manager ? )
If i understand it right a Service if not bounded can run infinitely if it's not killed due to low memory problems, making it a foreground Service is the safest ?
Last thing and it's kind of a noob doubt, if the user leaves the application(Click Home Button or opens other app) the app is still in background but the activities are in "Paused" or "Stopped" mode will the Service still be able to talk to them ?
Sorry for long post and thank you.
Your requirement : after every x minutes, start a service, pull some date, update UI.
Solution :
Define or set an alarm for every x minutes, to trigger a receiver.
From receiver start the service.
In the service, start an async task to fetch the data in doInBackGround().
Once data is fetched, from onPostExecute() send a broadcast to your activity.
In the activity have a dynamic receiver registered for broadcast sent from service.
From dynamic broadcast receiver update UI.
From what you've explained I wouldn't personally use a service.
The Android docs on services explain more but here is a snippet:
http://developer.android.com/guide/components/services.html
A Service is an application component that can perform long-running operations in the background and does not provide a user interface.
You could perhaps looks at using an AsyncTask, especially given that you only want it to run whilst the app is running:
http://developer.android.com/reference/android/os/AsyncTask.html
This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
There is a good answer here on how to run an AsyncTask repeatedly at specific time intervals: How to execute Async task repeatedly after fixed time intervals

Android: AsyncTask vs Service

Why do I read in the answer to most questions here a lot about AsyncTask and Loaders but nothing about Services? Are Services just not known very well or are they deprecated or have some bad attributes or something? What are the differences?
(By the way, I know that there are other threads about it, but none really states clear differences that help a developer to easily decide if he is better off using the one or the other for an actual problem.)
In some cases it is possible to accomplish the same task with either an AsyncTask or a Service however usually one is better suited to a task than the other.
AsyncTasks are designed for once-off time-consuming tasks that cannot be run of the UI thread. A common example is fetching/processing data when a button is pressed.
Services are designed to be continually running in the background. In the example above of fetching data when a button is pressed, you could start a service, let it fetch the data, and then stop it, but this is inefficient. It is far faster to use an AsyncTask that will run once, return the data, and be done.
If you need to be continually doing something in the background, though, a Service is your best bet. Examples of this include playing music, continually checking for new data, etc.
Also, as Sherif already said, services do not necessarily run off of the UI thread.
For the most part, Services are for when you want to run code even when your application's Activity isn't open. AsyncTasks are designed to make executing code off of the UI thread incredibly simple.
Services are completely different: Services are not threads!
Your Activity binds to a service and the service contains some functions that when called, blocks the calling thread. Your service might be used to change temperature from Celsius to Degrees. Any activity that binds can get this service.
However AsyncTask is a Thread that does some work in the background and at the same time has the ability to report results back to the calling thread.
Just a thought: A service may have a AsyncTask object!
Service is one of the components of the Android framework, which does not require UI to execute, which mean even when the app is not actively used by the user, you can perform some operation with service. That doesn't mean service will run in a separate thread, but it runs in main thread and operation can be performed in a separate thread when needed.
Examples usages are playing music in background, syncing data with server in backgroud without user interaction etc
AsyncTask on other hand is used for UI blocking tasks to be performed on a separate thread. It is same like creating a new thread and doing the task when all the tasks of creating and maintaining the threads and send back result to main thread are taken care by the AsyncTask
Example usage are fetching data from server, CRUD operations on content resolver etc
Service and asynctasks are almost doing the same thing,almost.using service or a asynctask depends on what is your requirement is.
as a example if you want to load data to a listview from a server after hitting some button or changing screen you better go with a asynctask.it runs parallel with main ui thread (runs in background).for run asynctack activity or your app should on main UI thread.after exit from the app there is no asynctask.
But services are not like that, once you start a service it can run after you exit from the app, unless you are stop the service.like i said it depends on your requirement.if you want to keep checking data receiving or check network state continuously you better go with service.
happy coding.
In few cases, you can achieve same functionality using both. Unlike Async Task, service has it's own life cycle and inherits Context (Service is more robust than an Async Task). Service can run even if you have exited the app. If you want to do something even after app closing and also need the context variable, you will go for Service.
Example: If you want to play a music and you don't want to pause if user leaves the app, you will definitely go for Service.
Comparison of a local, in-process, base class Service✱ to an AsyncTask:
✱ (This answer does not address exported services, or any service that runs in a process different from that of the client, since the expected use cases differ substantially from those of an AsyncTask. Also, in the interest of brevity, the nature of certain specialized Service subclasses (e.g., IntentService, JobService) will be ignored here.)
Process Lifetime
A Service represents, to the OS, "an application's desire to perform a longer-running operation while not interacting with the user" [ref].
While you have a Service running, Android understands that you don't want your process to be killed. This is also true whenever you have an Activity onscreen, and it is especially true when you are running a foreground service. (When all your application components go away, Android thinks, "Oh, now is a good time to kill this app, so I can free up resources".)
Also, depending on the last return value from Service.onCreate(), Android can attempt to "revive" apps/services that were killed due to resource pressure [ref].
AsyncTasks don't do any of that. It doesn't matter how many background threads you have running, or how hard they are working: Android will not keep your app alive just because your app is using the CPU. It has to have some way of knowing that your app still has work to do; that's why Services are registered with the OS, and AsyncTasks aren't.
Multithreading
AsyncTasks are all about creating a background thread on which to do work, and then presenting the result of that work to the UI thread in a threadsafe manner.
Each new AsyncTask execution generally results in more concurrency (more threads), subject to the limitations of the AsyncTasks's thread-pool [ref].
Service methods, on the other hand, are always invoked on the UI thread [ref]. This applies to onCreate(), onStartCommand(), onDestroy(), onServiceConnected(), etc. So, in some sense, Services don't "run" in the background. Once they start up (onCreate()), they just kinda "sit" there -- until it's time to clean up, execute an onStartCommand(), etc.
In other words, adding additional Services does not result in more concurrency. Service methods are not a good place to do large amounts of work, because they run on the UI thread.
Of course, you can extend Service, add your own methods, and call them from any thread you want. But if you do that, the responsibility for thread safety lies with you -- not the framework.
If you want to add a background thread (or some other sort of worker) to your Service, you are free to do so. You could start a background thread/AsyncTask in Service.onCreate(), for example. But not all use cases require this. For example:
You may wish to keep a Service running so you can continue getting location updates in the "background" (meaning, without necessarily having any Activities onscreen).
Or, you may want to keep your app alive just so you can keep an "implicit" BroadcastReceiver registered on a long-term basis (after API 26, you can't always do this via the manifest, so you have to register at runtime instead [ref]).
Neither of these use cases require a great deal of CPU activity; they just require that the app not be killed.
As Workers
Services are not task-oriented. They are not set up to "perform a task" and "deliver a result", like AsyncTasks are. Services do not solve any thread-safety problems (notwithstanding the fact that all methods execute on a single thread). AsyncTasks, on the other hand, handle that complexity for you.
Note that AsyncTask is slated for deprecation. But that doesn't mean your should replace your AsyncTasks with Services! (If you have learned anything from this answer, that much should be clear.)
TL;DR
Services are mostly there to "exist". They are like an off-screen Activity, providing a reason for the app to stay alive, while other components take care of doing the "work". AsyncTasks do "work", but they will not, in and of themselves, keep a process alive.

Categories

Resources