效果圖


部分源碼和理解說明
一個基于okhttp的文件下載、上傳工具
下載:支持多線程、斷點續(xù)傳下載,以及下載管理,原理、以及用法
上傳:支持表單形式上傳、直接將文件作為請求體上傳,原理、以及用法
批量下載

這些就是簡單類的方法了。
先串聯(lián)起來就必須有簡單單個下載方式。

這樣就是一個簡單的方式了。
通過這個思路繼續(xù)下去,開始批量,進行梳理。
同單例來保障數(shù)據(jù)獲取和下載的獨立性
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 來封裝獲取數(shù)據(jù)來源問題進行統(tǒng)一。
DownloadProgressHandler 來進行 Handler 數(shù)據(jù)進行回到和梳理。
FileTask 和ThreadPool 來進行真正的下載功能,在task是一個run方式,對于,每次下載還進處理并記錄,從而可以導(dǎo)向的進行每個下載的文件進行合理的顯示。
/**
* data + callback 形式直接開始下載
*
* @param downloadData
* @param downloadCallback
* @return
*/
public DownloadManger start(DownloadData downloadData, DownloadCallback downloadCallback) {
execute(downloadData, downloadCallback);
return downloadManager;
}
這個是先通過進行分配和添加,導(dǎo)致可以進行合理的分配處理下載的進度。
然后在進行分離開。
/**
* 根據(jù)url開始下載(需先注冊監(jiān)聽)
*
* @param url
*/
public DownloadManger start(String url) {
execute(downloadDataMap.get(url), callbackMap.get(url));
return downloadManager;
}
/**
* 注冊監(jiān)聽
*
* @param downloadData
* @param downloadCallback
*/
public synchronized void setOnDownloadCallback(DownloadData downloadData, DownloadCallback downloadCallback) {
downloadDataMap.put(downloadData.getUrl(), downloadData);
callbackMap.put(downloadData.getUrl(), downloadCallback);
}
根據(jù)url開始下載(需先注冊監(jiān)聽) 這注冊的時候,就是下載碼setcallback ....
這樣就很好的看到了,我們下載 下載內(nèi)容了。
/**
* 執(zhí)行下載任務(wù)
*/
private synchronized void execute(DownloadData downloadData, DownloadCallback downloadCallback) {
//防止同一個任務(wù)多次下載
if (progressHandlerMap.get(downloadData.getUrl()) != null) {
return;
}
//默認每個任務(wù)不通過多個異步任務(wù)下載
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);
//如果正在下載的任務(wù)數(shù)量等于線程池的核心線程數(shù),則新添加的任務(wù)處于等待狀態(tài)
if (ThreadPool.getInstance().getThreadPoolExecutor().getActiveCount() == ThreadPool.getInstance().getCorePoolSize()) {
downloadCallback.onWait();
}
}
這里不得不看 單例里面四個主要的靜態(tài)的變量了。
private Map<String, DownloadProgressHandler> progressHandlerMap = new HashMap<>();//保存任務(wù)的進度處理對象
private Map<String, DownloadData> downloadDataMap = new HashMap<>();//保存任務(wù)數(shù)據(jù)
private Map<String, DownloadCallback> callbackMap = new HashMap<>();//保存任務(wù)回調(diào)
private Map<String, FileTask> fileTaskMap = new HashMap<>();//保存下載線程
對著四個進行添加和刪除的過程就行下載和完成的過程了。
增加部分
1,批量上傳
批量處理方式根據(jù)批量下載思路來的,這樣就必須搞清楚批量下載。然后開始著手去創(chuàng)建,相同的文件和類。

發(fā)現(xiàn)上傳 不會續(xù)傳,后臺根本沒有這樣做,失敗了重新上傳,或者提示上傳失敗就完了,
省下了存數(shù)據(jù)的煩惱了。
/**
* 根據(jù)url開始下載(需先注冊監(jiān)聽)
*
* @param uploadData
*/
public UploadManger start(UploadFile uploadData) {
execute(uploadData, callbackMap.get(uploadData.getFile().getAbsolutePath()));
return downloadManager;
}
/**
* 注冊監(jiān)聽
*
* @param uploadData
* @param uploadCallback
*/
public synchronized void setOnDownloadCallback(UploadFile uploadData, UploadCallback uploadCallback) {
uploadDataMap.put(uploadData.getFile().getAbsolutePath(), uploadData);
callbackMap.put(uploadData.getFile().getAbsolutePath(), uploadCallback);
}
/**
* 執(zhí)行上傳任務(wù)
*/
private synchronized void execute(UploadFile uploadData, UploadCallback uploadCallback) {
//防止同一個任務(wù)多次上傳
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);
}
這樣 先簡化掉線程上傳,回調(diào)等問題,先進行去操作可以批上傳,進行邏輯。
列表代碼


最后加一鍵批量下載

public void startAll(ArrayList<UploadFile> uploadFiles) {
for (UploadFile bean : uploadFiles) {
start(bean);
}
}