How to cancel Current instance of AsyncTask and starts new one? - android

I have a file downloading android application.Here file is downloaded when user click on listview items.It works fine.
Now,I want to cancel current file download and start next file while user taps on other items and another download is already progressing and show user confirmation before canceling the download task.
How can i do this?
Thanks in Advance

First, you must check in your AsyncTask
// in doInBackground, check if asynctask is canceled manually
if (isCancelled()) break;
In your activiy, whenever you try to cancel, just cancel AsyncTask manually, and of course, start a new one to download another file!
mDownloadingTask.cancel(true);

Simply , you store your Asynctask to a variable:
mDownloadingTask = new Asynctask(){...};
mDownloadingTask.execute();
When you want to stop this task and start new one:
//close the current task if it # null
mDownloadingTask.cancel(true);
mDownloadingTask = null;
//Start new one
mDownloadingTask = new Asynctask(){...};
mDownloadingTask.execute();

Cancel(false) sets a flag, which you can check in doInBackGround() and stop your code from doing what its doing. cancel(true) does the same except it also interrupts the thread. See more info about interrupts here.
This is all good when you have a looped code in your task. Every iteration of the loop, you can check isCancelled().
But as in your question, some tasks like downloading a file do not use loops, perhaps you are just calling an external API method, so here, you are on the mercy of this blocking method. If well designed, it will throw an exception when interrupted, and the thread will terminate.
Also, have a look at a better implementation, SafeAsyncTask

Related

Checking the completion of Android background thread

After loading the first activity, my application immediately starts downloading some files in a background process (I use new Thread() for this).
In the first activity, there is also a button which opens the second activity. It is crucial for the second activity that the background download is finished.
My task:
If user clicks on the button while the background download is not yet finished, the application must wait and not open the second activity. It must show a message like "Please wait" instead.
If in XX seconds after clicking download is not finished either, another message (with OK button) appears: "You have a too slow connection."
Have your thread broadcast a "completed" action to the main thread and stash this result.
Then on the UI thread you can check this variable to proceed.
you can check using
Thread myThread; //your thread that is downloading thigns
if(myThread.isAlive())
{
//do what you want here
}
You need to use AsyncTask for this.
Using its override methods.

AsyncTask and error when executed twice

I use an asynctask in my app that downloads some data from the internet. If this task is executed twice within seconds, user presses the button twice, I get an IllegalState error saying a task can not be execute twice. If the user waits about 30 seconds, everyting is fine.
Then I tried to use AsyncTask.getStatus(), like this, to only execute when the task was NOT RUNNING, ie executed when status was PENDING or FINISHED, but this only worked the first time when the getStatus() was PENDING. If it was FINISHED, the same IllegalState error was produced.
Then I tried to follow an other example, saying the a new object of the AsyncTask should be created each time it is supposed to be executed. This seems to work.
So my question is, is it not possible to use one instance of an asynctask object and reexecute it? If so, how come it can be done if you wait long enought (like 30 seconds)?
No. You cannot execute the same async task twice. You are able to do it again after 30 secs because the async task completes processing and returns the result from doInBackground(). Hence you need to create an object every time or use a progress dialog to block the user from clicking on the button again. Show the progress dialog in onPreExecute() and dismiss in onPostExecute().
You can use one instance of an asynctask object and reexecute it, I use this and work for me:
if(yourAsyncTaskInstance!=null &&
yourAsyncTaskInstance.getStatus() == AsyncTask.Status.FINISHED){
yourAsyncTaskInstance = new YourAsyncTaskClass();
yourAsyncTaskInstance.execute();
}
WIthout seeing your code, it's difficult to know why it might be working after a 30 second wait, but, you are correct: as the docs say, "The task can be executed only once (an exception will be thrown if a second execution is attempted.)"

ReExecute AsyncTask

I have several AsyncTask in my Project to grab data from some given apis.
I followed the following steps.
1) execute an Async Task and try to grab datas from there.
2) check conditions for internet and server down
3) if any issue in api or internet or server then show dialog [custom from self made class]
4) dismiss button for canceling the dialog and go back to the working stage of `app may be even by closing the activity`
My problem is I want to keep a Button "Retry" such that it shall be re executing the AsyncTask.
I searched of passing AsyncTask but it seemed worthless as I concluded AsyncTask cannot be passed. And so I am forced to repeat same code cancel(true) for various times
It would be very useful if anyone could give me solution for it with this code re-use concept.
You cannot "retry" the same AsyncTask object - you can only call AsyncTask#execute() once. However, you could create a new AsyncTask instance when the user decides to retry the download task.
Solved The problem by using a retry button that creates the new object of class implementing Async-task and executing that new object.

Dynamically update doInBackground params in AsyncTask

Just wondering if there is a possible way to update the data of AsyncTask's doInBackground. Like for example rotating an image, I use bitmap which I want to update each time the UI thread gets a new data, I want to pass that data to AsyncTask which it can work in the background.
Any tips for that? Thanks
AsyncTask is meant to do a small amount of work and exit. They are not meant for long running operations, so it wouldn't be appropriate to try to pass new data into it.
It sounds like what you should do is:
UI gets a new image
Start a new async task to process the image. Store task in member variable.
If UI gets a new image again, check if existing async task is still running. Either cancel that task and start a new one, or discard the new image and let the current task run to completion.

Two different AsyncTasks execute at the same time

I have two total different implementations of AsyncTask, lets say AT1 and AT2.
AT1 is executed first, then AT2 is executed. AT1 waits in doInBackground until AT2 has done its task by polling this data every 500 ms. But this never happens.
So what I basically want is this:
But what seems to happen is this:
Except AT1 is never done, and AT2 is never started.
Is there a way I can force these two AsyncTasks to be executed on two seperate threads, or is there another solution for this?
It is not possible to first start AT2 and after that execute AT1.
EDIT
For clarification: AT1 is executed when a user opens a particular screen, and needs to download data for that screen, based on a location. AT2 is executed on Location change, and when that happens, some calculations are made that cannot be done on the UI thread.
When AT2 has never been executed, AT1 has no location to download data for, so it needs to wait for AT2 to finish. When AT2 has been executed, the location data is already there, and AT1 doesn't need to wait.
Also, this problem occurs in ICS, not in Android 2.3, like this answer suggests.
When I posted this question, this question appeared in the Related section.
It advices to use executeOnExecutor, I've implemented this as follows:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
new SetLocationAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, location);
} else {
new SetLocationAsyncTask().execute(location);
}
What's the point of having two async tasks, if one waits for the other? And if you want to do it, why not have the first one start the second one and put the "done" stuff in the second task?
Sounds like you may need to rethink your logic - if you're kicking off a thread which then needs to wait for another thread to do some work, why not just have the first thread do that work?
If you really need 2 AsyncTasks, have the first one gather whatever data is needed and don't kick off the second until after the first is finished - have a read about onPostExecute in the docs.

Categories

Resources