i am importing contacts in to a file using asynchronous task it is going well but after starting asynchronous task if i want to cancel it on middle then how to stop it means which have been done before stooping async task should be null and stop the asynch task..my code is below pls help me..
A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)
I would have
while(!iscancelled())
as the while condition. So when your cancel button is pressed, call cancel(true) on your AsyncTask. This will cause the while condition to be false. doInBackground will then exit.
If you implementation onCancel this will be called after doInBackground and you can set the contacts to null.
Hope that helps.
Override the method onCancelled() and in that set flag canceled = true;
and pass this canceled variable to condition in doInBackground.
Related
I am dealing with quite a bit of legacy AsyncTask code and have to write some myself too in our codebase. But, the careful reading of the cancel() method from the docs has confused me quite a bit. The docs say:
Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, already been cancelled, or could not
be cancelled for some other reason. If successful, and this task has
not started when cancel is called, this task should never run. If the
task has already started, then the mayInterruptIfRunning parameter
determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
Calling this method will result in onCancelled(Object) being invoked
on the UI thread after doInBackground(Object[]) returns. Calling this
method guarantees that onPostExecute(Object) is never invoked. After
invoking this method, you should check the value returned by
isCancelled() periodically from doInBackground(Object[]) to finish the
task as early as possible.
So, there might be a scenario where the AsyncTask has finished and returned from doInBackground() but before calling onPostExecute(), the task was canceled through cancel() which resulted in a call to onPostExecute() anyway. This might be dangerous if the cancellation was initiated from onPause() of Activity.
Also, this question on SO supports the documented behavior of cancellation: onPostExecute on cancelled AsyncTask
So, should I start checking for if(isCanceled()) at the start of onPostExecute() from now on?
So, should I start checking for if(isCanceled()) at the start of
onPostExecute() from now on?
Definetly not, it is already checked.
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
ref:AsyncTask.java
when calling
cancel(true);
on asyncTaskObj bring user to
onCancelled()
method. when and why
onCancelled(Object result)
will be called and what is the use of it?
A task can be cancelled at any time by invoking cancel(boolean).
Invoking this method will cause subsequent calls to isCancelled() to
return true.
After invoking this method, onCancelled(Object), instead of
onPostExecute(Object) will be invoked after doInBackground(Object[])
returns.
To ensure that a task is cancelled as quickly as possible, you should
always check the return value of isCancelled() periodically from
doInBackground(Object[]), if possible (inside a loop for instance.)
description for cancel() function
description for isCancelled() function
description for onCancelled() function
Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object),
instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns.
it is from Android Developer documentation developer.android.com/reference/android/os/AsyncTask.html
You may check isCancelled() to finish the working of doInbackground if it has loop
protected Object doInBackground(Object... obj) {
while (/* condition */) {
//.......
if (isCancelled()) break;
}
return myReturn;
}
This is from the documentation...
Runs on the UI thread after cancel(boolean) is invoked and doInBackground(Object[]) has finished.
The default implementation simply invokes onCancelled() and ignores the result. If you write your own implementation, do not call super.onCancelled(result).
Obviously, it gives you the chance to react after the operation has finally been cancelled such as changing the state of some UI components or notifying the user. For example, say you are executing a long running operation such as downloading a file, while the file is downloading you display a progress bar, but you also expose a "cancel" button so that the user can cancel the download.
Once cancel is clicked you can stop the progress bar and display a "Cancelling..." text when "onCancelled" is triggered you can hide the "cancel" button, the status text view and the progress bar.
What happens when AsncTask get cancelled.
Does it still calls onPostExecute().
Answer is NO .as doc says:
public final boolean cancel (boolean mayInterruptIfRunning) :
Calling this method guarantees that onPostExecute(Object) is never
invoked. After invoking this method, you should check the value
returned by isCancelled() periodically from doInBackground(Object[])
to finish the task as early as possible.
from the official java doc:
A task can be cancelled at any time by invoking cancel(boolean).
Invoking this method will cause subsequent calls to isCancelled() to
return true. After invoking this method, onCancelled(Object), instead
of onPostExecute(Object) will be invoked after
doInBackground(Object[]) returns. To ensure that a task is cancelled
as quickly as possible, you should always check the return value of
isCancelled() periodically from doInBackground(Object[]), if possible
(inside a loop for instance.)
And method java doc:
public final boolean cancel (boolean mayInterruptIfRunning)
Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, already been cancelled, or could not
be cancelled for some other reason. If successful, and this task has
not started when cancel is called, this task should never run. If the
task has already started, then the mayInterruptIfRunning parameter
determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
Calling this method will result in onCancelled(Object) being invoked
on the UI thread after doInBackground(Object[]) returns. Calling this
method guarantees that onPostExecute(Object) is never invoked. After
invoking this method, you should check the value returned by
isCancelled() periodically from doInBackground(Object[]) to finish the
task as early as possible.
I am using an Android AsyncTask in order to download files from a server. when files are downloaded, I am trying to kill the AsyncTask.
protected void onPostExecute(Void result) {
MyTask.cancel(true);
}
But it stills running (I can see it from the Debug window in eclipse).
How to kill the AsyncTask?
When the AsyncTask is finished running, onPostExecute() will be called. The thread will die. The garbage collector will clean it up. You don't have to do anything. What you're doing is redundant.
Other than that, calling "Cancel" sends and interrupt signal to the thread. If your process can be interrupted, it will stop blocking and continue to execute. You then have to call isCancelled() in doInBackground() and return from the method if isCancelled() is true. After which, onCanceled() and onPostExecute() will be called and the thread will die on it's own like normal.
There is some documentation from here about canceling an AsyncTask, which may be relevant:
A task can be cancelled at any time by invoking cancel(boolean).
Invoking this method will cause subsequent calls to isCancelled() to return true.
After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns.
To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)"
The Problem is:
My Activity starts an AsyncTask in onStart().
In the doInBackground Method I make a short webrequest, and depending on your network connetion, this may take a little, so I want this task cancelable...
BUT..
After hours of searching, testing and debugging I noticed now, when the user presses the back button during the doInBackground Method, the Keyevent ist always dispatched AFTER my doInBackground method is finished.
So I dont have to wonder why the asynctask never is cancelled when the users presses the backbutton,
the AsyncTask.cancel(true) is invoked too late..... (even if I am not sure if cancel(true) will help)
So is this normal behavoiur with asynctask and backbutton?
This cant be normal, because how should the user ever get back from the activity on slow connection?
wait for timeout?
I am Begging for Help, cancel an async webrequest SHOULD be possible :)
when the user presses the back button during the doInBackground Method, the Keyevent is always dispatched AFTER my doInBackground method is finished.
No, this isn't true.
If I hit the BACK button on my device when an AsyncTask is running in my main Activity (downloading files from my server), the Activity is immediately closed.
What IS true, however, is the AsyncTask will continue to run whatever code is in its doInBackground() method UNLESS I explicitly cancel it (but you kind of know that already).
As far as I can tell, your 'webrequest' (whatever that may be) is blocking your doInBackground() method and because of that, any attempt to cancel it in onPause(), onStop, onDestroy() etc will never work.
As advantej points out, the way the AsyncTask.cancel(...) method works is that it causes isCancelled to be set to 'true'. In order to successfully cancel the AsyncTask's doInBackground() method you need to periodically check isCancelled. Example...
#Override
protected Void doInBackground(String... params) {
while (!isCancelled) {
DoSomething();
}
}
The problem is if DoSomething() (for example your 'webrequest') is blocking the while loop then isCancelled won't be checked until it completes.
This is the expected behavior. The documentation says :
Cancelling a task
A task can be cancelled at any time by
invoking cancel(boolean). Invoking
this method will cause subsequent
calls to isCancelled() to return true.
After invoking this method,
onCancelled(Object), instead of
onPostExecute(Object) will be invoked
after doInBackground(Object[])
returns. To ensure that a task is
cancelled as quickly as possible, you
should always check the return value
of isCancelled() periodically from
doInBackground(Object[]), if possible
(inside a loop for instance.)