I have an app that makes numerous RESTful service calls. I execute the calls in a class extending Asynctask. If I have to cancel the asynctask, I also want to cancel the service call. Unfortunately, cancelling the async operation still allows doInBackground to complete and I can't call isCancelled() once the request is waiting for a response (which can take a little bit). Right now, from within my doInBackground method I'm registering to be notified from the UI thread if a cancel request is made, so I can abort the HttpResponse object. Here is a piece of sample code.
It has worked so far, but can I really count on it, or am I just getting lucky? Can you count on one thread to call a method in another thread?
public class AsyncTestActivity extends Activity {
private ArrayList<IStopRequestMonitor> monitors;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
}
public void stopActivity() {
if (monitors == null || monitors.size() < 1) return;
for (int i = 0; i < monitors.size(); i++) {
monitors.get(i).stopRequest();
}
}
public void addListener(IStopRequestMonitor listener) {
if (monitors == null) monitors = new ArrayList<IStopRequestMonitor>();
monitors.add(listener);
}
public void readWebpage(View view) {
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { "http://www.mywebsite.com/feeds/rsstest.xml" });
}
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
DefaultHttpClient client = new DefaultHttpClient();
final HttpGet httpGet = new HttpGet(urls[0]);
addListener(new IStopRequestMonitor() {
public void stopRequest() {
if (httpGet == null) return;
httpGet.abort();
cancel(true);
}
});
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
// handle inputstream
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
@Override
protected void onPostExecute(String result) {
Log.d("Result:", result);
}
}
interface IStopRequestMonitor {
public void stopRequest();
}
}