我有一个应用程序可以打很多restful服务电话。我在扩展asynctask的类中执行调用。如果必须取消asynctask,我还想取消服务调用。不幸的是,取消异步操作仍然允许doinbackground完成,而且一旦请求等待响应(可能需要一点时间),我就无法调用isCancelled()。现在,在doinbackground方法中,如果发出取消请求,我将注册从ui线程得到通知,这样我就可以中止httpresponse对象。这是一段示例代码。
到目前为止已经成功了,但我真的能指望它吗?还是我只是走运了?你能指望一个线程在另一个线程中调用一个方法吗?
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();
}
}
最佳答案
这里还有比赛。如果stopActivity()在后台线程调用addListener()之前运行,则稍后将添加侦听器,并且永远不会调用它来中止httpget。
如果要从UI线程(或在其上创建异步任务的任何线程)调用cancel(),可以:
在异步任务中创建“private httpget httpget”字段。
重写onPreExecute()并在那里初始化HttpGet。
重写onCancel()并说“if(httpget!=空){httpget.abort()}
在doinBackground()中,如果取消,则立即返回,否则运行。
因为这会在ui线程上初始化httpget,所以cancel()调用将在execute()之前运行(因此doinbackground将看到iscancelled()返回true),或者在httpget存在之后运行,因此httpget将被中止。
你不需要听者,除非你把它用在别的事情上。