使用mayInterruptIfRunning取消ASyncTask - 函数调用顺序 -

时间:2011-12-20 01:23:29

标签: android android-asynctask

当我致电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语句)

2 个答案:

答案 0 :(得分:4)

所以我发现了一些事情(我想我明白发生了什么)......

我认为在doInBackground返回后将调用onCancelled函数而不是onPostExecute ...而是在AyncTask.cancel()函数时调用onCancelled被称为。

所以我遇到的问题是,使用我的代码,将关闭并删除doInBackground线程正在处理的数据库。所以大部分时间,该线程都会崩溃(在logcat中没有看到太多,但大多数时候,它会进入检查if (isCancelled()) ...

刚刚更改了此任务的组织,现在工作正常。创建一个单独的函数来执行清除,当doInBackground返回true时,isCancelled将调用该函数。没有使用onCancelled来做任何事情......

答案 1 :(得分:0)

只有在以这种方式编码时,您才能在doInBackground()中检测到取消。这种“检测”不是通过异步回调。换句话说,doInBackground()应定期检查取消状态,并处理已请求取消的情况。您可以发布doInBackground()的片段吗?