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

Android Download Manager暂停恢复后卡顿问题及替代方案咨询

Android 下载暂停与恢复的替代实现方案

你当前使用的Download Manager暂停恢复方式依赖系统私有Content URI(content://downloads/my_downloads),这种非官方API本身存在性能兼容性隐患,卡顿大概率是系统处理该更新操作时的内部开销导致的。以下是几种更可靠的实现方式:

1. 基于OkHttp的自定义下载逻辑(推荐)

直接通过OkHttp实现断点续传,完全掌控暂停恢复流程,彻底避免私有API的问题。核心原理是:

  • 下载前记录已下载的文件大小,恢复时通过Range请求头告知服务器从指定位置继续传输
  • 调用Call.cancel()实现暂停,恢复时重新构建请求并设置Range头

示例代码:

private OkHttpClient client = new OkHttpClient();
private Call currentDownloadCall;
private long downloadedBytes = 0;
private File targetFile;

// 启动或恢复下载
public void startOrResumeDownload(String downloadUrl) {
    Request.Builder requestBuilder = new Request.Builder().url(downloadUrl);
    
    // 如果已有部分下载内容,设置断点续传的Range头
    if (downloadedBytes > 0 && targetFile.exists()) {
        requestBuilder.addHeader("Range", "bytes=" + downloadedBytes + "-");
    }

    Request request = requestBuilder.build();
    currentDownloadCall = client.newCall(request);
    
    currentDownloadCall.enqueue(new Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            // 处理下载失败逻辑
        }

        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
            if (!response.isSuccessful()) {
                // 处理响应错误,比如416表示服务器不支持Range请求
                return;
            }

            InputStream inputStream = response.body().byteStream();
            // 以追加模式打开文件输出流,避免覆盖已下载内容
            FileOutputStream outputStream = new FileOutputStream(targetFile, true);

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                // 检查下载是否被暂停
                if (call.isCanceled()) {
                    outputStream.close();
                    inputStream.close();
                    return;
                }
                outputStream.write(buffer, 0, bytesRead);
                downloadedBytes += bytesRead;
                // 此处可添加进度更新逻辑
            }

            outputStream.close();
            inputStream.close();
            // 下载完成处理
        }
    });
}

// 暂停下载
public void pauseDownload() {
    if (currentDownloadCall != null && !currentDownloadCall.isCanceled()) {
        currentDownloadCall.cancel();
    }
}

2. 结合WorkManager实现后台可控下载

如果需要在后台稳定执行下载任务,同时支持暂停恢复,可以借助WorkManager:

  • 暂停时取消对应的WorkRequest
  • 恢复时创建新的OneTimeWorkRequest,传入已下载字节数,在Worker内部设置Range头继续下载
  • 优势是系统会自动管理后台任务生命周期,降低被系统杀死的概率

3. 使用成熟第三方下载库

不少第三方库已经封装了完善的断点续传、暂停恢复逻辑,无需重复造轮子:

  • AndroidDownloader:基于OkHttp开发,支持多任务并行、断点续传、暂停恢复等功能
  • Retrofit + OkHttp:通过自定义CallAdapter扩展下载能力,同样可利用Range头实现断点续传

通用注意事项

  • Android 10及以下需申请WRITE_EXTERNAL_STORAGE权限,Android 10+建议使用Scoped Storage存储下载文件
  • 需监听网络状态变化,网络断开时自动暂停,恢复网络后可继续下载
  • 大文件下载务必在后台线程执行,避免阻塞主线程导致ANR

内容的提问来源于stack exchange,提问作者mohammad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:55:20