如何在用户退出Activity时中止Jsoup网页下载请求?
如何在退出Activity时中止Jsoup的网页下载请求?
问题描述
我使用Jsoup实现了一个简单的AsyncTask用于下载网页,希望在用户退出Activity时能够中止该请求,但未找到对应的实现方法。以下是我的代码:
public class JsoupDownloader extends AsyncTask<String, Integer, Document> { public enum AsyncResponseType { TYPE_A, TYPE_B } private GenericAsyncResponse delegate = null; private AsyncResponseType responseType; private Connection connection; public JsoupDownloader(GenericAsyncResponse delegate, AsyncResponseType responseType){ this.delegate = delegate; this.responseType = responseType; } @Override protected Document doInBackground(String... urls) { Document doc = null; try { connection = Jsoup.connect(urls[0]); doc = connection .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36") .get(); } catch (IOException ex){ Log.e("JosoupDownloader", "IOException when downloading "+urls[0]); } return doc; } @Override protected void onProgressUpdate(Integer... progress) { //setProgressPercent(progress[0]); } @Override protected void onPostExecute(Document response) { delegate.processFinish(response, responseType); } }
我了解HttpURLConnection类拥有disconnect()方法,请问Jsoup是否有类似方法可用于中止下载请求?
解决方案
好问题!Jsoup本身并没有直接提供中止请求的API,但它底层默认依赖HttpURLConnection,所以我们可以通过获取底层连接并调用disconnect()来实现请求中止,再结合AsyncTask的取消机制,就能完美解决你的需求。
步骤1:修改JsoupDownloader,保存底层HttpURLConnection
首先,我们需要拆分Jsoup的请求流程,拿到并保存底层的HttpURLConnection对象:
public class JsoupDownloader extends AsyncTask<String, Integer, Document> { public enum AsyncResponseType { TYPE_A, TYPE_B } private GenericAsyncResponse delegate = null; private AsyncResponseType responseType; private Connection connection; private HttpURLConnection httpURLConnection; // 新增:保存底层连接 public JsoupDownloader(GenericAsyncResponse delegate, AsyncResponseType responseType){ this.delegate = delegate; this.responseType = responseType; } @Override protected Document doInBackground(String... urls) { Document doc = null; try { connection = Jsoup.connect(urls[0]) .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"); // 拆分请求流程,先获取Response再解析Document Response response = connection.execute(); // 拿到底层的HttpURLConnection httpURLConnection = (HttpURLConnection) response.connection(); doc = response.parse(); } catch (IOException ex){ // 判断是否是用户主动取消导致的异常 if (isCancelled()) { Log.i("JsoupDownloader", "Request cancelled by user"); } else { Log.e("JsoupDownloader", "IOException when downloading "+urls[0], ex); } } return doc; } // 新增:自定义的取消请求方法 public void cancelRequest() { // 标记AsyncTask为取消状态 cancel(true); // 断开底层连接 if (httpURLConnection != null) { httpURLConnection.disconnect(); Log.i("JsoupDownloader", "Request disconnected successfully"); } } @Override protected void onProgressUpdate(Integer... progress) { //setProgressPercent(progress[0]); } @Override protected void onPostExecute(Document response) { // 只有当任务未被取消时,才回调结果 if (!isCancelled()) { delegate.processFinish(response, responseType); } } }
步骤2:在Activity退出时调用取消方法
在你的Activity的onDestroy(或onStop)方法中,调用cancelRequest()来中止请求:
private JsoupDownloader jsoupDownloader; // 初始化下载任务的代码示例 private void startDownload() { jsoupDownloader = new JsoupDownloader(this, JsoupDownloader.AsyncResponseType.TYPE_A); jsoupDownloader.execute("https://example.com"); } @Override protected void onDestroy() { super.onDestroy(); // 检查任务是否存在且未被取消,然后中止请求 if (jsoupDownloader != null && !jsoupDownloader.isCancelled()) { jsoupDownloader.cancelRequest(); } }
补充说明
- 调用
cancel(true)会将AsyncTask标记为取消状态,此时isCancelled()会返回true,我们可以在doInBackground和onPostExecute中检查这个状态,避免执行后续不必要的逻辑。 - 断开
HttpURLConnection后,Jsoup的请求会立即抛出IOException,我们可以在catch块中区分是正常异常还是取消导致的异常,方便日志排查。 - 注意:AsyncTask在Android API 30及以上已被标记为Deprecated,如果是新项目,推荐使用Coroutines结合ViewModel,或者用OkHttp这类自带取消机制的网络库来实现更可靠的请求管理。
内容的提问来源于stack exchange,提问作者materight
相关产品推荐
相关产品推荐

