Preventing concurrency in a duplicated service - android

I'm using an IntentService to sync my SQLite database (managed by a Content Provider) with a webservice. My problem is that the service is triggered when the user refreshes the screen, hence there can be more of one service running at the same time. I'm afraid that might cause concurrency issues: data corruption for example.
My question is: Is there an "Android" way to prevent this to happen? Or do I have to build a queueing system myself? I know I could do put my whole service code in an atomic block, but I'm looking for something more elegant.
Thanks!

IntentService already handle for you a queueing system. From the documentation:
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.
IMHO if you want a more robust and elegant solution to sync your ContentProvider with a webservice you should create a SyncAdapter which is much more powerful (it can even monitor your ContentProvider and trigger the webservice call).

If the service is being triggered by Intents, then it will follow the normal lifecycle and the callbacks will get hit on the main UI thread of your app's process. The service is not re-spawned with multiple instances. If you spawn your own background thread or AsyncTask in the service to do some heavy lifting for you (i.e. process your data) then you'll need to protect things accordingly.

Related

Asynctask vs IntentService for syncing with backend mysql server

My application does a sync process every 30 seconds.
What I do is, send some data, and accordingly get a set of data, and update/insert into my local sqlite DB. Sometimes, I updated my GUI as a result of these operations.
I read in several posts that an asynctask can do this task perfectly, and in some other posts many people discouraged the use of asynctask, and told me to implement the intentService/broadcast receiver approach.
Which one is better? and when ?
There are multiple considerations that you must weigh in order to best decide how to approach your situation. Acording to the doc:
...an activity that initiates a long-running
operation might do well to start a service for that operation, rather
than simply spawn a thread — particularly if the operation will likely
outlast the activity. Examples of this are playing music in the
background and uploading a picture taken by the camera to a web site.
Using a service guarantees that the operation will have at least
"service process" priority, regardless of what happens to the
activity.
A Service is a part of your Application that has no UI. It may be called by a UI(Activity) to be started, or may be started by any other component of your Application. When developing, you have the freedom to place it on a different thread, or even run it in a different Task or Process. This allows you to ultimately separate it from your UI. Additionally, you may start the Service to run independently (startService) or bind your activity to it (bindService) depending upon your needs. By using custom Handlers, you can set callbacks to update the UI with your progress. A Service does not necessarily end if a User changes Activities, but may be ended at ANY time by the OS.
A AsyncTask is always instantiated from the UI thread. It only allows specific callbacks, but simplifies the process of multi-threading for the purposes of relatively short transactions (as compared to dedicated separate threaded services) that are inherently tied to actions performed by an Activity. Whenever a User changes Activities, the AsyncTask is put on "pause" and may even die because there is no UI thread for your Activity any longer.
The problem with the AsyncTask is if the user goes to another Activity you can't transfer that object to the other Activity so it dies. There are tricks you can play when say the user rotates the screen or something like that, but that doesn't extend to general purpose destruction. AsyncTask can randomly die. On the other hand you can definitely communicate between Service and Activity, but it's tricky to do it right.
So, depending on your scenario, you have to take a design decision.
If you need to update the UI then AsyncTask will be a better fit, however if you need it to update in the background when the app is not running then IntentService would be better and you will need to come up with a way to update the UI from your IntentService
This is more of an opinion based question so I would not expect one definite answer. Its a per-app basis question

Is it better to use AsyncTask (Or Timer) within single process, or using Service in separate process?

I just read Android Architecture Tutorial: Developing an App with a Background Service (using IPC). It is basically
Have a service run in separate process.
A repeated timer event will occur in the service.
Within the timer event handler, it will perform networking to retrieve tweet, and inform all the listener attached to it. Listeners are attached to it through IPC.
I can see there are 2 major characteristics with this approach.
Tweet retrieving action run within separate process.
It always run, even the main activity has quit.
However, if "It always run" is not my requirement. I want everything to stop when I quit my main Activity.
Will it be better, if I use AsyncTask (Or Timer) within my main Activity, to perform tweet retrieving action? Everything will be run within single process. No more using Service.
Using AsyncTask (Or Timer), seems simpler. We no longer need to deal with IPC.
Or, using Service approach might be better? Am I missing some goodies provided by Service?
Using service is a better approach as it will allow you to perform the polling independent from the application flow.
As it is a task where no user interaction is required and it has to be done in the background without disturbing the main UI of application and whatever the user is doing, a service is an ideal candidate for its implementation.
It is possible to bind the service with the application in such a way that when the main application terminates, it will also turn off the service.
I would take the view that a TimerTask can be set to execute and repeat at a given interval, Timers run on a separate thread so all this work would occur in the background without disturbing the UI. It would be easy for you to trigger an update within your app when the TimerTask completes and update the UI when you want.
When you exit the app it's a simple case of calling cancel() on your Timer and the purging all the tasks with purge().
Nice and easy and you don't need to implement IPC, which can be very fiddly to get right.
EDIT
Using AsyncTask you can do pretty much exactly the same thing but you'll have to manually schedule the next run. I have used both solutions in the past and found them to work equally well so it's all down to your preference.
At first you have to know, that a service isn't a Thread. If a activity binds a Service and runs as a Deamon, but a ASynchTask is another thread.
ASynchTask's are designed for doing some work which should not running on UI-Thread (for example processing some larger calculations)
Services are designed to run permanantly on Background.
If you want to permanantly check for new tweets, even if your activity is stopped or paused, you should use a Service, which checks into an own thread for new data.
TimerTask are good old java style implementations which run on their own thread.
You can used them for processing some data, but you'll have some problems to manipulation UI. If you want to be it on propper "AndroidWay", use a Handler instead of TimerTask.
First of all, I know the tutorial you are following...I've followed that tutorial myself while trying to learn IPC. One thing you need to know is, The Android docs explicitly say,
Note: Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service.
If at all possible, you should just bind to the service.
Also, you must consider, do you really need a service? Consider that the Android Twitter app doesn't even refresh tweets for you, its on an as needed basis. Polling can be battery intensive, so you must consider if this is really necessary.
Also, will you be using these tweets from multiple activities? If so it would be nice to not duplicate the code in multiple places. So maybe you do want a service in this case.
Other than that, I would recommend that you start simple (Async task with a timer to update it), and move to a service if you think you need it.

Why would one use AsyncTasks when you can use Services?

When you learn to develop for Android, you learn that if there's any type of process -that takes more that 5 seconds- running inside the ui thread, the system will show the infamous ANR message. That's when they introduce the evil monster... AsyncTask. At first you see this class as your savior, but then you realize it's the biggest problem in development... Handling rotation or ui events becomes so problematic, it's even painful.
What do you guys think about it... are AsyncTasks worth the trouble? Any other method that makes it less of a problem to perform long running tasks regardless of screen rotation?
I guess you'll probably say, hey why don't you just make it a Service... Yeah that's a solution, but then let's go to my real question. Why don't we just use services and stop using AsyncTasks completely... Are they useful at all?
While developing it is always good to choose the suitable component for the execution. You need to clear your requirement and according to it you can choose between a Service or an AsyncTask.
A service is an Android component that lives independently from any other components. Activities may come and go, but services can stick around, if you wish. They serve a number of roles, from managing state that multiple activities rely upon to serving as cron jobs to handling longer app widget updates.
AsyncTask is a class that arranges to do some work off the main application thread. From the implementer and user of the AsyncTask, how it performs that bit of magic is not generally important. In reality, it uses a thread pool and work queue. AsyncTask uses a Handler to help arrange for select bits of work to be done on the main application thread (e.g., notifying the user of progress updates).
For more clarification see the difference between them.
AsyncTasks and Services are not peers. Either might invoke the other, their purposes are different. I have just a few things to add to Lucifer's answer.
A key thing to remember is that if your process is in the background, hosts a Service, and is killed, that Service will be reincarnated at some point. This is not the case for an AsyncTask that may be running in a process when it is killed. This means that work being done in a Service is guaranteed to make forward progress in the future (although its not guaranteed when). If you have work that must be done, better to do it in a Service.
Calls to Service.onStart and Service.onStartCommand happen on the process' main thread. If you block this for a long time, you'll get the same "app not responding" dialog. As a result, an AsyncTask can be a great thing to use inside a Service to do the real work.
I tend to use AsyncTasks initiated from an Activity for things related to the UI. These are often things that aren't required work and whose work can be easily redone in the future. For example, this might be reading a bunch of images off disk or make a calling to a web service to see if the user has any notifications. This work can be done again, and if the UI is destroyed because the process is killed the work probably needs to be done again anyway.
If on the other hand you want to say upload a group of photos to the web as soon as possible, I'd farm this out to a Service which will use one or more AsyncTasks to do it. This is work I want to get done and want to be resumed if it gets interrupted. If you're going to use a Service, consider using an IntentService so that your Service stops when its work is done.

AsyncQueryHandler vs IntentService?

Looking at the source code for the stock Calendar app, Google uses an IntentService to do the content provider operations for the database. Is there an advantage to using an IntentService rather than a AsyncQueryHandler?
I thought that since a Handler is tied to the UI, if the activity gets paused or stopped, the Handler would also get paused. However, this doesn't seem to be the case: I created a simple content provider and AsyncQueryHandler that do nothing but run through a long for loop. When I launch other apps or kill the activity, the for loop still runs.
So is the advantage of using an IntentService for asynchronous CRUD operations that the service (being a service) has less of a chance of getting killed?
Update: Part of my confusion is how a handler relates to an activity's lifecycle. From my experiment, it seems that it's independent.
Also, for those not familiar with the stock Calendar app source code, the way it works is that to do a CRUD, it adds the operation to a queue along with a reference to a handler. Then it starts the intent service which pops the queue and does the CRUD. When it's finished, it invokes the handler via Message.sendToTarget().
So what does that extra complexity buy us?
I am stuck with the same confusion. What I found is the IntentService will get killed with the activity. This also means that it will get killed on Orientation change. While an AsyncQueryHandler will keep on running(as you found out). In my use case I am updating my UI first without waiting for the database to update. So I think I am gonna opt for AsyncQueryHandler.
I don't know much about Intent Service(never used it) but as it is sending messages It might be useful when you need something from database to show on the UI thread..so that you know when the database was updated.

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