无法取消android中的异步任务

时间:2013-01-11 14:00:23

标签: android asynchronous task

我需要取消我的asyncthread。在我的应用程序中,我正在做一些繁重的计算,我想让用户能够取消计算(然后重试)。我在论坛上看到,你不能只是停止它正在做什么的任务,你需要在你的DoinBackground代码中检查任务是否为isCancelled = true。但那对我不起作用。

任务本身运行良好,如果我让它自行结束,它会输出正确的数据。

在我的应用程序中,我首先调用函数naredi_pdf_start(view),然后当任务运行时,如果我调用close_pdf1(view),它会给我一个错误。(我正在更改视图,app无法找到我的pdf_text1 Textview当调用publishProgress- null指针异常时)。我真的不知道如何使用task.cancel(true)方法(在我的例子中:start_pdf.cancel(true)))。

这是我的代码:

String progress_pdf;
naredi_pdf start_pdf;

public void naredi_pdf_start(View view) {
    start_pdf=new naredi_pdf();
    start_pdf.execute();
}

public void close_pdf1(View view) {

    if(start_pdf!=null) {
        Log.v("not null","not null");

        start_pdf.cancel(true);
        setContentView(R.layout.other_view); //This is where 
                                             //I don't have TextView pdf_text1
    }
}

private class naredi_pdf extends AsyncTask<Void, String, Void> {

    protected Void doInBackground( Void... ignoredParams ) {
        progress_pdf="Calculating Statistical Data";

        //A LOT OF CODING

        for(int i = 0; i < 1; i++) {
            if(isCancelled()) {
                break;
            }
            else {
                publishProgress("Calculating team statistics");  
            }
        }

        //MORE OF CODING              

        for (int i = 0; i < 1; i++) {
            if (isCancelled()) {
                break;
            }
            else {
                publishProgress("Calculating player's BIO");  
            }
        }

        //MORE OF CODING       

        for (int i = 0; i < 1; i++) {
            if (isCancelled()) {
                break;
            }
        else {
                publishProgress("Calculating player's individual performance");
            }
        }

        return null; 
    }

    protected void onPostExecute( Void array ) {
        //saving to database
    }

    protected void onProgressUpdate(String... values) {
        progress_pdf=values[0]+"\n"+progress_pdf;

        if (isCancelled())  {

        }
        else {
            TextView pdf_text1 = (TextView) findViewById (R.id.pdf_text1);
            pdf_text1.setText(progress_pdf);
            // dialog(view);
        }
    }
}

3 个答案:

答案 0 :(得分:2)

return语句取消执行doInBackground方法,而不是break

答案 1 :(得分:2)

您的问题不在于您无法取消AsyncTask。您可能会收到NullPointerException,因为在setContentView()成功之前,您对AsyncTask.cancel()的来电已经过去了。调用onProgressUpdate()只会发现布局现在已更改且View没有id=R.id.pdf_text1

来自AsyncTask的文档。

  

可以通过调用cancel(boolean)随时取消任务。调用此方法将导致后续调用isCancelled()返回true。调用此方法后,将在doInBackground(Object [])返回后调用onCancelled(Object)而不是onPostExecute(Object)。为确保尽快取消任务,应始终定期从doInBackground(Object [])检查isCancelled()的返回值(如果可能)(例如在循环内)。

由于onCancelled()在UI线程上运行,并且您确定不会发生对onProgressUpdate()的后续调用,因此它是调用setContentView()的好地方。

覆盖onCancelled()

中的AsyncTask
private class naredi_pdf extends AsyncTask<Void, String, Void> {

    protected Void doInBackground( Void... ignoredParams ) { // YOUR CODE HERE}
    protected void onPostExecute( Void array ) { // YOUR CODE HERE}
    protected void onProgressUpdate(String... values) {// YOUR CODE HERE}

    // ADD THIS
    @Override
    protected void onCancelled() {
        // Do not call super.onCancelled()!

        // Set the new layout
        setContentView(R.id.other_layout);
    }
}

更改close_pdf1()

public void close_pdf1(View view) {
    if(start_pdf!=null) {
        Log.v("not null","not null");

        start_pdf.cancel(true);
    }
}

你应该有AsyncTask在取消时自动更改你的布局。希望您不应该遇到任何NullPointerException。但是没有尝试过代码:)

修改

如果您觉得有意思,请按照Rezooms的建议使用return

for(int i = 0; i < 1; i++) {
    if(isCancelled()) {
        return null;
    }
    .
    .
    .
}

答案 2 :(得分:0)

是Canceled是AsyncTask类的专有方法。

您应该在扩展类上定义一个私有布尔属性,执行类似这样的操作

private class myAsyncTask extends AsyncTask<Void, String, Void> {
          private boolean isTaskCancelled = false;

          public void cancelTask(){
               isTaskCancelled = true;
          }

          private boolean isTaskCancelled(){
               return isTaskCancelled;
          }

          protected Void doInBackground( Void... ignoredParams ) {
            //Do some stuff
             if (isTaskCancelled()){
                return;
             }
          }


          protected void onPostExecute( Void array )
          {
           //Do something
          }



          protected void onProgressUpdate(String... values)
          {
           //Do something
          }
    }