取消AsyncTask时执行onPostExecute

时间:2013-03-31 03:59:46

标签: android android-asynctask

据我所知,一旦调用AsyncTask,结果将更改为null并取消AsyncTask。有没有办法保留结果并将其传递给onPostExecute(String result)developer.android.com表示不要明确调用这些函数。

该应用程序基本上扫描图像,如果用户取消异步任务,我希望异步任务显示到目前为止扫描的图像。因此,结果不应设置为null。

这有可能实现吗?如果是,怎么样?

class openCVOperation extends AsyncTask<String, String, String>{
    private MainActivity context = null;
    /*lots of variables here*/
    public openCVOperation(MainActivity context1) {
        context = context1;// set context from mainActivity
                                        // which
                                        // inherits Activity super class.
                                        // Needed
                                        // for accessing widgets.
    }

    @Override
    protected void onPreExecute() {
        pd = new ProgressDialog(context);
        pd.setIndeterminate(false);
        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pd.setMax(100);
        pd.setCancelable(true);
        pd.setCanceledOnTouchOutside(false);
        pd.setMessage("Starting up");
        pd.show();
    }
    @Override
    protected String doInBackground(String... params) {
        publishProgress("Finding path to Storage...");
        path = Environment.getExternalStorageDirectory();
        p = path.getAbsolutePath();
        p=p+"/location";
        rm(p);// this has a loop!
        return null;

    }
    @Override
    protected void onCancelled()
    {
        System.out.println("In onCancelled");
        super.onCancelled();
    }
@Override
    protected void onPostExecute(String result) {
        pd.dismiss();
        /*post execute stuff*
    }

rm(p)有一个循环,因此我尝试使用isCancelled()作为条件,但这不起作用。

4 个答案:

答案 0 :(得分:1)

在doInBackground中

if (isCancelled())
{
    return // image so far
}


onPostExecute(String result)
{

     // show result
}

答案 1 :(得分:1)

我只需将其添加到我的doInBackground()

pd.setOnCancelListener(new DialogInterface.OnCancelListener() {

            @Override
            public void onCancel(DialogInterface dialog) {
                // TODO Auto-generated method stub
                task.cancel(true);
            }
        });

pd是我的进度对话框。

另外,请务必检查isCancelled()中的doInBackground(),否则永远不会调用onCancelled(),应用程序将强行关闭。

答案 2 :(得分:0)

收集结果:

public class MyTask extends AsyncTask<Void,Void,Void>{
  private final List<String> data;

  public MyTask(){
    data =  new ArrayList<String>();
  }

  public synchronized List<String> getData(){
    return new ArrayList<String>(data); //--current data snapshot--
  }

  private synchronized collect(String s){
    data.add(s);
  }     

  @Override
  public Void doInBackground(Void...args){
    //---do stuff--
    collect(/*-stuff-*/);
  }
}

即使线程被中断,你也不会丢失任何东西。

答案 3 :(得分:-1)

如果未调用onCancelled,则您的rm方法仍在运行。 因为如你所说,它正在运行循环。

控制流程的最佳方式(知道是否需要停止)是通过轮询或繁琐地检查volatile boolean方法中rm变量的状态。

例如,在名为static volatile boolean的AsyncTask类中创建一个cancel变量。在false方法中将此变量设置为onPreExecute

rm方法中,检查繁重任务之前和之后cancel是否为真(打开文件,读取文件,下载循环的一部分)。

如果是,则使用return语句中断方法。 更好的是,让你的rm方法返回一个Integer,0表示Good,1表示取消。

最后,在doInBackground方法返回之前,看看是否需要在线程上调用取消。

public class asyncTask extends AsyncTask<Void, Void, Void>
{
    private static synchronized boolean cancel;

    protected void onPreExecute()
    {
        cancel = false;
    }

    protected String doInBackground(Void ... params)
    {

        rm(p);

        if(cancel)
            asyncTask.cancel;
        else
            return null;
    }

    protected void onCancelled()
    {
        // only executed if doInBackground resulted in a cancel == true
    }

    protected void onPostExecute(Void param)
    {
        /// only executed if doInBackground resulted in a cancel == false 
    }

    private int rm(String str)
    {
        if(cancel)
            return 1;

        //do part of task

        if(cancel)
            return 1;

        //another part of task

        if(cancel)
            return 1;

        //another part of task

        return cancel ? 1 : 0;
    }

}