0

据我了解,一旦调用 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

4 回答 4

1

在 doInBackground

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


onPostExecute(String result)
{

     // show result
}
于 2013-03-31T04:17:26.737 回答
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()永远不会被调用,并且应用程序将强制关闭。

于 2013-03-31T06:19:05.210 回答
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-*/);
  }
}

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

于 2013-03-31T06:20:27.697 回答
-1

如果onCancelled没有被调用,那么您的rm方法仍在运行。因为正如你提到的,它正在运行一个循环。

控制进程(知道是否需要停止)的最佳方法是轮询或检查方法中volatile boolean变量的状态rm

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

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

return如果它是真的,那么用一个语句打破这个方法。更好的是,让您的rm方法返回一个整数,0 表示良好,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;
    }

}
于 2013-03-31T05:23:45.373 回答