Reputation: 4383
As far as I understand once an AsyncTask is called, the result is changed to null and the AsyncTask is cancelled. Is there a way to retain the result and pass it to onPostExecute(String result)
. developer.android.com
says not to call these functions explicitly.
The app basically scans images and if a user cancels the async task, I'd like the async task to display the images scanned so far. So the result should not be set to null.
Is this possible to accomplish? If yes, how?
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)
has a loop, so I tried using isCancelled()
as a condition, but that didn't work.
Upvotes: 0
Views: 2050
Reputation: 4383
I just had to add this to my doInBackground()
pd.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
task.cancel(true);
}
});
Where pd
is my progress dialog.
Also make sure you check for isCancelled()
in doInBackground()
or onCancelled()
will never be invoked and the application will force close.
Upvotes: 1
Reputation: 29436
Collect the results:
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-*/);
}
}
You won't lose anything even if thread is interrupted.
Upvotes: 0
Reputation: 1155
If onCancelled
is not being called, then your rm
method is still running.
Because as you mentioned, it's running a loop.
The best way to control the process (know if it needs to be stopped) is by polling or tediously checking the status of a volatile boolean
variable within your rm
method.
For example, create a static volatile boolean
variable within your AsyncTask class called cancel
. Set this variable to false
in the onPreExecute
method.
In your rm
method, check to see if cancel
is true before and after the heavy tasks (opening a file, reading a file, part of a download loop).
If it's true, then break out of the method with a return
statement.
Better yet, make your rm
method return an Integer, 0 for Good and 1 for cancelled.
And finally, right before the doInBackground
method hits return, see if you need to call a cancel on the thread or not.
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;
}
}
Upvotes: -1
Reputation: 18151
In the doInBackground
if (isCancelled())
{
return // image so far
}
onPostExecute(String result)
{
// show result
}
Upvotes: 1