【发布时间】:2013-02-27 23:21:45
【问题描述】:
我见过几个other post 关于取消 AsynTask,但我认为它们中的任何一个都不能解决问题。想象一下这个场景:
public class TestTask extends AsyncTask<Void, Void, Object> {
@Override
protected void onCancelled(Object result) {
running = false;
Log.i("Test", "onCancelled");
}
@Override
protected Object doInBackground(Void... params) {
try {
Log.i("Test", "cancelling");
cancel(true);
Thread.sleep(5000);
Log.i("Test", "Past sleep");
} catch (InterruptedException e) {
Log.i("Test", "InterruptedException", e);
}
return null;
}
}
假设我想在下载过程中取消这个长达 20 秒的长请求,例如,如果服务器对 json 请求的响应速度很慢。所以 Thread.sleep(5000) 可能是我想取消的 HttpGet 请求。但是,取消方法被标记为最终方法,因此我无法覆盖它并调用 get.abort()。 onCancel 钩子发生在 doInBackground 之后并返回 UI 线程。一旦 HttpGet 请求开始,检查 isCancel 对我没有任何好处。
我解决这个问题的方法是在我的 AsynTask 上创建一个 abort() 方法,然后调用它。
public void abort() {
get.abort();
cancel(true);
}
但这似乎有点违背 Android 的原则。有没有更好的方法来取消请求?
【问题讨论】:
-
您是否还需要从
InputStream中读取字节以进行连接?您只需在流上调用read时检查任务isCancelled,与您链接到的问题的答案中显示的完全相同。取消任务后,它将立即终止下载。如果您指的是等待超时,您可以在HttpUrlConnection上使用setReadTimeout。 -
没有。我说的是想要使用 HttpGet.abort()。使用 httpClient.execute(HttpGet) 时使用 AsynTask 时无法调用此方法。如果我在“执行”之后检查 isCancelled() 并且执行已经完成。我想中止下载,而不仅仅是停止它之后的逻辑。
-
@ebarrenchea 有正确的答案,但没有提到您应该在
doInBackground()中检查isCancelled(),理想情况下会在其中读取流。请参阅cancelling anAsyncTask部分。 -
这不会取消Http请求。它只会停止进一步执行。