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

Android平台批量PDF下载速度过慢的优化方案咨询

优化Android批量PDF下载速度的方案

当前实现了一键下载PDF列表功能,采用Foreground Service结合Android DownloadManager处理任务,初始入队6个PDF,每完成一个再加入下一个。现在91个总大小约40MB的PDF下载耗时1-2分钟,以下是可落地的加速方案:


现有核心代码

启动下载队列函数

private void startDownloadQueue() 
{
    for(int i=0;i<6;i++){
        if(i<hashMap.size()) {
            listIndex++;
            initiateDownload(documentList.get(i), positionList.get(i), hashMap.size());
        }
    }
}

private void initiateDownload(DocumentJsonModel.Document doc, int pos, int listSize)
{
    if (doc != null && isDownloading) {
        String position = String.valueOf(pos);
        String docId = doc.id;
        String docFile = doc.file;
        String docName = doc.name;
        String docDescription = doc.description;
        boolean isJustView = false;
        isFromSearch = false;

        long id = downloadFile(doc, docId, docFile, docName, docDescription, position, isJustView, listSize);
        if (id != 0) {
            setProgressUpdate(id, Integer.parseInt(position), Integer.parseInt(docId), isJustView, doc, listSize);
        } else if (isJustView) {
            Intent intent1 = new Intent(INTENT_FILTER_ACTION_OPEN_DOC);
            intent1.putExtra("docID",docId);
            intent1.putExtra("position",pos);
            intent1.putExtra("fromDownloadAll", true);
            intent1.putExtra("docId", docId);
            sendBroadcast(intent1);
            stopForeground(true);
            stopSelf();
        } else if (isFromSearch) {
            Intent intent1 = new Intent(INTENT_FILTER_ACTION_OPEN_DOC_FROM_SEARCH);
            intent1.putExtra("fromDownloadAll", true);
            intent1.putExtra("position", pos);
            intent1.putExtra("docId", docId);
            sendBroadcast(intent1);
            stopForeground(true);
            stopSelf();
        }
    }
}

DownloadManager入队方法

public long downloadFile(DocumentJsonModel.Document doc,String docId, String docFile, String docName, String description, String position, boolean isJustView, int listSize) {
    long downloadReference = 0;
    String root = "/twoway/saved_documents/";
    String BASE_DIR = getExternalFilesDir(null).getPath();

    File dir = new File(BASE_DIR + root);
    File file = new File(dir, docId + "_" + docFile);
    if(!isCancelledButtonPressed) {
        if (!file.exists()) {
            String fileUrl = DOCUMENT_URL + docFile;
            fileUrl = fileUrl.replaceAll(" ", "%20");

            Uri fileUri = Uri.parse(fileUrl);
            //Create request for android download manager
            DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
            DownloadManager.Request request = new DownloadManager.Request(fileUri);
            //set title for download
            request.setTitle(docName);
            request.setVisibleInDownloadsUi(false);
            //request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION);
            //Setting description of request
            request.setDescription(description);

            request.setDestinationInExternalFilesDir(this, null, "/twoway/saved_documents/"
                    + docId + "_" + docFile);

            //Enqueue download and save into referenceId
            downloadReference = downloadManager.enqueue(request);
        }
    }
    return downloadReference;
}

加速优化方案

1. 提高并发下载数量

DownloadManager本身支持多任务并发,系统默认并发数高于6,可尝试提高初始并发数(建议8-10,避免触发服务器限流),同时保持任务完成后自动补位,维持高并发状态:

private void startDownloadQueue() 
{
    // 调整初始并发数为8,可根据实际测试结果微调
    int initialConcurrent = 8;
    for(int i=0;i<initialConcurrent;i++){
        if(i<hashMap.size()) {
            listIndex++;
            initiateDownload(documentList.get(i), positionList.get(i), hashMap.size());
        }
    }
}

2. 优化DownloadManager请求配置

  • 添加超时设置,避免因请求挂起浪费时间
  • 明确允许移动网络+WiFi下载(如果业务允许)
// 在downloadFile方法的Request配置中添加
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setTimeout(30000); // 设置30秒超时

3. 批量预处理文件检查

当前每个下载任务都要单独检查文件是否存在,可提前批量筛选待下载文件,减少重复IO操作:

// 新增批量检查方法,在启动队列前调用
private List<DocumentJsonModel.Document> getPendingDownloads() {
    List<DocumentJsonModel.Document> pending = new ArrayList<>();
    final String DEST_DIR = "/twoway/saved_documents/";
    File dir = new File(getExternalFilesDir(null), DEST_DIR);
    if (!dir.exists()) {
        dir.mkdirs();
    }
    for (DocumentJsonModel.Document doc : documentList) {
        File file = new File(dir, doc.id + "_" + doc.file);
        if (!file.exists() && !isCancelledButtonPressed) {
            pending.add(doc);
        }
    }
    return pending;
}

之后基于这个待下载列表启动任务,减少downloadFile中的重复检查逻辑。

4. 复用DownloadManager实例

当前每次调用downloadFile都重新获取DownloadManager实例,可在Service初始化时创建全局实例复用:

private DownloadManager downloadManager;

@Override
public void onCreate() {
    super.onCreate();
    downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
}

// 在downloadFile方法中替换原获取实例的代码,直接使用全局的downloadManager

5. 服务器端协同优化(若可干预)

  • 开启PDF文件的Gzip压缩,减少传输体积
  • 将文件部署到CDN节点,降低下载延迟
  • 调整服务器单IP并发请求限制,避免被限流

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:35:23