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
相关产品推荐
相关产品推荐

