2011-12-20 36 views
3

当我打电话cancel(false)阻止我ASyncTask,我发现我之前也能够检测任务使用isCancelled()doInBackground()在被取消的onCancelled()函数被调用。用法取消的AsyncTask - 函数调用顺序 -

我试图将取消功能的参数更改为true,但这也没有帮助。

当我阅读文档时,我的理解是,我将能够检测doInBackground()中的取消,该函数返回并且仅在调用onCancelled()函数代替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()电话直接转到onCancelled()而另一个线程仍在运行。

一个可能的原因可能是this message我刚发现...?(我我对升级Froyo)运行此

更多...

虽然我在cancel()通话设置为false旗,我发现doInBackground()函数没有机会完成或检测消除(甚至从来没有得到一个返回声明)

+0

AysncTask.cancel()返回一个布尔值,告诉取消是否成功,返回值是什么?如果它是真的,那么你可能在execute()后过早调用cancel(),而AsycnTask实际上并没有启动。 – yorkw 2011-12-20 02:36:30

回答

4

那么一两件事情,我发现(我想我明白发生了什么事)...

我以为onCancelled函数会被调用,而不是onPostExecute后doInBackground返回...相反,在调用AyncTask.cancel()函数时调用onCancelled

所以我遇到的问题是,用我的代码,这将关闭并删除线程doInBackground正在处理的数据库。所以大多数情况下,那个线程只会崩溃(在logcat中没有看到太多,但大多数情况下,它会去检查if (isCancelled()) ...

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

0

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