Android批量處理上傳和下載

效果圖

GIF 2021-9-8 10-25-13.gif

GIF 2021-9-8 14-11-24.gif

部分源碼和理解說明

一個基于okhttp的文件下載、上傳工具

下載:支持多線程、斷點續(xù)傳下載,以及下載管理,原理、以及用法

上傳:支持表單形式上傳、直接將文件作為請求體上傳,原理、以及用法

批量下載

image.png

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


image.png

這樣就是一個簡單的方式了。
通過這個思路繼續(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)建,相同的文件和類。


image.png

發(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)等問題,先進行去操作可以批上傳,進行邏輯。

列表代碼

image.png
image.png

最后加一鍵批量下載


image.png
public void startAll(ArrayList<UploadFile> uploadFiles) {
        for (UploadFile bean : uploadFiles) {
            start(bean);
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容