问题
I am trying to execute the following AsyncTask :
private class TimeUpdateTask extends AsyncTask<List<mObject>, Integer, Void> {
@Override
protected Void doInBackground(List<mObject>... params) {
mObject o;
int i;
int numChecked = 0;
List<mObject> mObjects = params[0];
while(true)
{
if (isCancelled())
{
Log.w("TAG", "task interrumped");
return null;
}
for (i=0 ; i < mObjects.size() ; i++)
{
o = mObjects.get(i);
if (!o.isChecked())
{
o.calculateProgress();
if (o.isChecked())
{
numChecked++;
}
}
}
publishProgress(numChecked);
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
@SuppressWarnings("unchecked")
@Override
protected void onProgressUpdate(Integer... param){
int progressCompleted = param[0];
((ArrayAdapter<mObject>) EventListView.this.EventView.getAdapter()).notifyDataSetChanged();
mMain.setProgressBarCompleted(progressCompleted);
}
/*This should execute*/
@Override
protected void onPostExecute(Void result) {
Log.d("TAG","End onPostExecute");
}
}
So when I call cancel(false)
on this task, onPostExecute
should be executed but it never is.
Is there any problem in the code or something else?
I have looked at a lot of answers in SO and it seems that having #5 AsyncTask
hanging around is normal, even if you are using only one (as in my case) at the moment.
回答1:
There is 1 large piece missing here that you must learn about.
from the developer docs (see bold text below): http://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)
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.
回答2:
Android use onCancelled() when the task is cancelled, it don't call onPostExecute!
回答3:
I think calling cancel actually cancels everything from executing, including the onPostExecute. You should use your own local boolean variable and do this:
private boolean shouldContinue = true;
public void customCancel()
{
shouldContinue = false;
}
then in your loop do this:
if (!shouldContinue)
{
Log.w("TAG", "task interrumped");
return null;
}
来源:https://stackoverflow.com/questions/8219115/asynctask-never-executes-onpostexecute