You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在用户退出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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:13:04