据我所知,一旦调用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()
作为条件,但这不起作用。
答案 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;
}
}