Best way to periodically executing AsyncTasks in Android - java

I am getting data from the server using AsyncTask. I need to update the data periodically.
Whats the best way to do it?

You could use Timer class to schedule periodic task using TimerTask instead of AsyncTask
See :
http://developer.android.com/reference/java/util/Timer.html
http://developer.android.com/reference/java/util/TimerTask.html
And to update your UI you should follow this good tutorial :
http://android-developers.blogspot.com/2007/11/stitch-in-time.html

Set an alarm with AlarmManager and call your AsyncTask in your AlarmReceiver class.

You can do it either on your onProgressUpdate() or on onPostExecute() based on your requirement.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
http://developer.android.com/intl/de/reference/android/os/AsyncTask.html

Just to state one of the possibilities. You could also use ScheduledThreadPoolExecutor class. It has, generally, more possibilities then TimerTask.

To elaborate upon macarse's response, you can indeed "set an alarm with AlarmManager and call your AsyncTask in your AlarmReceiver class."
The concern I raised in the linked post still stands: I don't know if there are any life cycle issues associated with instantiating an AsyncTask from a WakefulBroadcastReceiver, i.e., I don't know if the above solution can lead to MyAsyncTask being killed prematurely.

Related

Thread Runnable vs AsyncTask Life Cycle

I would like to better understand what happens to a Thread or a AsyncTask when activity is destroyed.
So in this scenario, a Thread or AsyncTask would be started from activity, and user hits home button and onDestroy gets called triggering GC before either Thread of AsyncTask had a chance to finish.
Which one is more likely to run till completion in this scenario Thread/Runnable or an AsyncTask ?
Thanks.
Both will run
But the problem is if you have a reference to the killed activity on Thread of AsyncTask it will leak, and that is a problem you need to solve to make long running tasks synchronized with UI
If you've got a bigger task, I'd suggest you to spin up a Service, which are more easy to handle in Android context
AsyncTask based on thread so there is no huge difference in it's behaviour both will run after onDestroy. To avoid this behaviour you could use Loaders or manually stop execution of AsyncTasks/Threads in onDestroy method.

Android: How to stop Thread.sleep in an IntentService from the MainActivity

I am developing an Android App. I have a MainActivity class where I launch an IntentService.
In the IntentService class, I use Thread.sleep in the method onHandleIntent to handle a necessary pause.
Everything works fine.
What I would like to do is have a button in the MainActivity UI which can interrupt the Thread.sleep in the IntentService.
Is this possible? Thank you.
No, it's not possible. You cannot handle non UI related threads from the main UI thread. A thread is an independent entity when it's executed. If you want to be able to cancel a task that is already running, you should consider using AsyncTask and implement the doInBackground() method. Thereafter, it's possible to cancel this task from the UI if it's still executing.
Try to consider using a Service instead of the IntentService. The first one doesn't stop automatically, meaning it will listen to your commands you could send to it (I would go with EventBus) unless it is destroyed by the system to reclaim resources. Still you should definitely stop it on your own after you don't need it.
Anyways, I would better implement start/pause feature to control your flow rather than rely on thread interruptions.

What can be happen if I use AsyncTask in IntentService?

I want to know. What can be happen, when I use AsyncTask in IntentService.
Once onHandleIntent() returns, the service will be destroyed if there is no more outstanding work to be done. If the AsyncTask is still running, you will have leaked that thread. There is no guarantee that your process will remain running long enough for the AsyncTask to complete its work.
Since IntentService already gives you a background thread -- the one that onHandleIntent() runs on -- there is no need for another background thread. Just put your doInBackground() logic in onHandleIntent() of the IntentService.
Also, in general, using an AsyncTask from any service is unnecessary, as the service has no need to do anything on the main application thread.
You can use aynchronous task inside intent service and it will run perfectly.Since , intentService is to run the background task without Ui interaction but it is better for one work not to use asychronous task inside intentService.It will be helpful when You are using more than one long operations in the intentService otherwise that will struck the device
I think it is a completely bad idea to execute AsyncTask inside IntentService. I have an experience of AsyncTask inside JobIntentService which is different from IntentService but it causes crash. Just put codes inside doInBackground() in onHandleIntent().

Android/Java . AsyncTask /Thread passing data back to UI whenever I want it(not only in pre/postExecute)

I am struggling with the some threading stuff in android.
The situation is, that I have a table, which is getting filled during ui actions of the user.
And this table is added to a queue. I chose LinkedBlockingQueue until now.
(Please correct me if this is a bad Idea).
At the same time there is a background-thread, that should fetch (read) the queue and prepare another table, which itself then is passed to a method, which should be invoked on the UI thread.
(Meaning, the background-thread only collects the queued table in background in order to pass them to another method later on ).
So I read about the various approaches to do this in some ways and found myself in the AsyncTask.
But AsyncTask only allows me pre execution or post execution as options to invoke methods/code in the UI thread.
I want to decide myself, when I invoke some methods on the UI thread , because the background-thread still has to do some work after he invoked the method in UI thread.
Ah, as information: The background-thread never stops unless the user exits the application or a special idle timeout occurred.
And : Invoking the mentioned method on UI thread will also be parametrized.
But async task only allows me pre execution or post execution as options to invoke methods/code in the ui thread.
No. onProgressUpdate() also runs on the UI Thread. You run this function by calling publishProgress() in doInBackground() when the UI needs to be update while background operations are still running.
Here is an answer with an example of using it
publishProgress() Docs
Make sure to read through the AsyncTask Docs thoroughly several times. They are a bit tricky at first until you get it.

Creating another AsyncTask inside of doInBackground

I recently looked through SO to find the answer to the same question here, but there was not an answer directed at the question in regards to the risk of doing so. But basically I want to run another AsyncTask inside the doInBackground() method of another AsyncTask. Is this a bad approach and/or does it leave any potential side effects?
I know that running it in the onPostExecute() works and so far from past experiences I have not had any issues due to the fact that onPostExecute() runs back on the main thread which started a AsyncTask to begin with.
From the API docs:
•The task instance must be created on the UI thread.
doInBackground() runs on the background thread. So you cannot create and run another asynctask from doInBackground().
http://developer.android.com/reference/android/os/AsyncTask. Have a look at the topic under threading rules.
When an asynchronous task is executed, the task goes through 4 steps: (Straight from the doc)
1.onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
2.doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
3.onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
4.onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.
Also you can consider using an alternative RoboSpice.https://github.com/octo-online/robospice.
Can make multiple spice request. Notitifes on the ui thread when task is complete. Worth having a look at robospice.
AsyncTask(), with the exception of the Honeycomb releases, execute serially. So, no, you cannot execute another AsyncTask() from within doInBackground() -- I guess I should say that I've never tried it, but it's highly unlikely you're going to achieve the desired affect.
I asked about AsyncTask() execution during one of the Google Office Hours. Straight from their mouths when asked, "Why did it change from serial to parallel and back to serial execution?"; "Because it broke a lot of stuff."

Categories