当我致电cancel(false)
停止我的ASyncTask
时,我发现onCancelled()
功能在我能够检测到doInBackground()
中的任务被取消之前就被调用了使用isCancelled()
。
我试图将cancel函数的参数更改为true,但这也无济于事。
当我阅读文档时,我的理解是我能够在doInBackground()
中检测到取消,从该函数返回并且仅在调用onCancelled()
函数代替{ {1}}。
我错过了什么吗?我是否需要添加更多同步机制以确保按照我期望的顺序发生事情?
编辑:
以下是代码的组织方式:
onPostExecute()
所以现在的问题是,即使在 AsyncTask<Void,Integer,Void>() {
ProgressDialog mProgressDialog;
@Override
protected Void doInBackground(Void... voids) {
for (int i=0; i<size; i++) {
publishProgress(i/100);
if (isCancelled()) {
Log.d(TAG, "getting out");
return null;
}
// do some database operations here
}
// do some house cleaning work also here
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// create the progress dialog if needed
mProgressDialog = new ProgressDialog(context);
mProgressDialog.setMessage("Do it!");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialogInterface) {
cancel(false);
}
});
mProgressDialog.setCancelable(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.show();
// create some database here
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
mProgressDialog.setProgress(values[0]);
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mProgressDialog.dismiss();
}
@Override
protected void onCancelled() {
super.onCancelled();
Log.d(TAG, "Cancelling !");
// since we are cancelling the operation, close and delete the database that was being created
mProgressDialog.dismiss();
}
}
中删除了数据库,仍然会对数据库执行某些操作。
症状是消息“退出”和“取消!”的顺序是不一致的(我也是用调试器做的,似乎onCancelled()
调用直接转到cancel()
,而另一个线程仍在运行。
一个可能的原因可能是this message我刚发现......? (我在Froyo上运行这个)
MORE ...
虽然我将onCancelled()
调用中的标志设置为false,但我发现cancel()
函数没有机会完成或检测到取消(它甚至永远不会返回到return语句)
答案 0 :(得分:4)
所以我发现了一些事情(我想我明白发生了什么)......
我认为在doInBackground返回后将调用onCancelled
函数而不是onPostExecute
...而是在AyncTask.cancel()函数时调用onCancelled
被称为。
所以我遇到的问题是,使用我的代码,将关闭并删除doInBackground
线程正在处理的数据库。所以大部分时间,该线程都会崩溃(在logcat中没有看到太多,但大多数时候,它会进入检查if (isCancelled())
...
刚刚更改了此任务的组织,现在工作正常。创建一个单独的函数来执行清除,当doInBackground
返回true时,isCancelled
将调用该函数。没有使用onCancelled
来做任何事情......
答案 1 :(得分:0)
只有在以这种方式编码时,您才能在doInBackground()
中检测到取消。这种“检测”不是通过异步回调。换句话说,doInBackground()
应定期检查取消状态,并处理已请求取消的情况。您可以发布doInBackground()
的片段吗?