Android批量处理上传和下载
2021-09-08 本文已影响0人
客观开发者
效果图
GIF 2021-9-8 10-25-13.gifGIF 2021-9-8 14-11-24.gif
部分源码和理解说明
一个基于okhttp的文件下载、上传工具
下载:支持多线程、断点续传下载,以及下载管理,原理、以及用法
上传:支持表单形式上传、直接将文件作为请求体上传,原理、以及用法
批量下载
image.png这些就是简单类的方法了。
先串联起来就必须有简单单个下载方式。
image.png
这样就是一个简单的方式了。
通过这个思路继续下去,开始批量,进行梳理。
同单例来保障数据获取和下载的独立性
private volatile static DownloadManger downloadManager;
public static DownloadManger getInstance(Context context) {
if (downloadManager == null) {
synchronized (DownloadManger.class) {
if (downloadManager == null) {
downloadManager = new DownloadManger(context);
}
}
}
return downloadManager;
}
private DownloadManger(Context context) {
this.context = context;
}
用DBuilder 来封装获取数据来源问题进行统一。
DownloadProgressHandler 来进行 Handler 数据进行回到和梳理。
FileTask 和ThreadPool 来进行真正的下载功能,在task是一个run方式,对于,每次下载还进处理并记录,从而可以导向的进行每个下载的文件进行合理的显示。
/**
* data + callback 形式直接开始下载
*
* @param downloadData
* @param downloadCallback
* @return
*/
public DownloadManger start(DownloadData downloadData, DownloadCallback downloadCallback) {
execute(downloadData, downloadCallback);
return downloadManager;
}
这个是先通过进行分配和添加,导致可以进行合理的分配处理下载的进度。
然后在进行分离开。
/**
* 根据url开始下载(需先注册监听)
*
* @param url
*/
public DownloadManger start(String url) {
execute(downloadDataMap.get(url), callbackMap.get(url));
return downloadManager;
}
/**
* 注册监听
*
* @param downloadData
* @param downloadCallback
*/
public synchronized void setOnDownloadCallback(DownloadData downloadData, DownloadCallback downloadCallback) {
downloadDataMap.put(downloadData.getUrl(), downloadData);
callbackMap.put(downloadData.getUrl(), downloadCallback);
}
根据url开始下载(需先注册监听) 这注册的时候,就是下载码setcallback ....
这样就很好的看到了,我们下载 下载内容了。
/**
* 执行下载任务
*/
private synchronized void execute(DownloadData downloadData, DownloadCallback downloadCallback) {
//防止同一个任务多次下载
if (progressHandlerMap.get(downloadData.getUrl()) != null) {
return;
}
//默认每个任务不通过多个异步任务下载
if (downloadData.getChildTaskCount() == 0) {
downloadData.setChildTaskCount(1);
}
DownloadProgressHandler downloadProgressHandler = new DownloadProgressHandler(context, downloadData, downloadCallback);
FileTask fileTask = new FileTask(context, downloadData, downloadProgressHandler.getHandler());
downloadProgressHandler.setFileTask(fileTask);
downloadDataMap.put(downloadData.getUrl(), downloadData);
callbackMap.put(downloadData.getUrl(), downloadCallback);
fileTaskMap.put(downloadData.getUrl(), fileTask);
progressHandlerMap.put(downloadData.getUrl(), downloadProgressHandler);
ThreadPool.getInstance().getThreadPoolExecutor().execute(fileTask);
//如果正在下载的任务数量等于线程池的核心线程数,则新添加的任务处于等待状态
if (ThreadPool.getInstance().getThreadPoolExecutor().getActiveCount() == ThreadPool.getInstance().getCorePoolSize()) {
downloadCallback.onWait();
}
}
这里不得不看 单例里面四个主要的静态的变量了。
private Map<String, DownloadProgressHandler> progressHandlerMap = new HashMap<>();//保存任务的进度处理对象
private Map<String, DownloadData> downloadDataMap = new HashMap<>();//保存任务数据
private Map<String, DownloadCallback> callbackMap = new HashMap<>();//保存任务回调
private Map<String, FileTask> fileTaskMap = new HashMap<>();//保存下载线程
对着四个进行添加和删除的过程就行下载和完成的过程了。
增加部分
1,批量上传
批量处理方式根据批量下载思路来的,这样就必须搞清楚批量下载。然后开始着手去创建,相同的文件和类。
image.png
发现上传 不会续传,后台根本没有这样做,失败了重新上传,或者提示上传失败就完了,
省下了存数据的烦恼了。
/**
* 根据url开始下载(需先注册监听)
*
* @param uploadData
*/
public UploadManger start(UploadFile uploadData) {
execute(uploadData, callbackMap.get(uploadData.getFile().getAbsolutePath()));
return downloadManager;
}
/**
* 注册监听
*
* @param uploadData
* @param uploadCallback
*/
public synchronized void setOnDownloadCallback(UploadFile uploadData, UploadCallback uploadCallback) {
uploadDataMap.put(uploadData.getFile().getAbsolutePath(), uploadData);
callbackMap.put(uploadData.getFile().getAbsolutePath(), uploadCallback);
}
/**
* 执行上传任务
*/
private synchronized void execute(UploadFile uploadData, UploadCallback uploadCallback) {
//防止同一个任务多次上传
if (progressHandlerMap.get(uploadData.getFile().getAbsolutePath()) != null) {
return;
}
uploadDataMap.put(uploadData.getFile().getAbsolutePath(), uploadData);
callbackMap.put(uploadData.getFile().getAbsolutePath(), uploadCallback);
Call upload = DUtil.initFormUpload()
.url("http://192.168.1.110:8080/file/uploadFile")
.addFile("file", uploadData.getFile().getName(), uploadData.getFile())
.fileUploadBuild()
.upload(uploadCallback);
progressHandlerMap.put(uploadData.getFile().getAbsolutePath(), upload);
}
这样 先简化掉线程上传,回调等问题,先进行去操作可以批上传,进行逻辑。
列表代码
image.png image.png最后加一键批量下载
image.png
public void startAll(ArrayList<UploadFile> uploadFiles) {
for (UploadFile bean : uploadFiles) {
start(bean);
}
}