0

我需要取消我的 asyncthread 。在我的应用程序中,我正在做一些繁重的计算,我想让用户能够取消计算(然后重试)。我在论坛上读到,您不能只是停止任务正在执行的操作,并且您需要检查任务 isCancelled=true 在您的 DoinBackground 代码中是否存在。但这对我不起作用。

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

在我的应用程序中,我首先调用函数 naredi_pdf_start(view),然后当任务运行时,如果我调用 close_pdf1(view),它会给我一个错误。(我正在更改视图并且应用程序在调用 publishProgress 时找不到我的 pdf_text1 Textview - 空指针异常)。我真的不知道如何使用 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);
        }
    }
}
4

3 回答 3

2

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

于 2013-01-11T14:10:28.617 回答
2

您的问题不在于您无法取消AsyncTask. 您可能会收到NullPointerException,因为您setContentView()之前的电话AsyncTask.cancel()已成功通过。AonProgressUpdate()被调用,却发现布局现在已更改,并且没有Viewwith 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;
    }
    .
    .
    .
}
于 2013-01-11T15:13:28.600 回答
0

isCancelled 是 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
          }
    }
于 2013-01-11T14:19:50.283 回答