下载工具类(带缓存)

    前言:由于项目里面经常需要用到下载,所以封装了一个下载工具类。
    实现方案:1.下载之前查找本地有没有缓存记录
                     2.如果有缓存记录,那么判断缓存文件是否存在,如果存在,直接回调下载结束,否则从网络下载
                     3.缓存的key采用文件下载url生成的md5
                     4.下载失败的时候删除片段文件

    项目链接:https://github.com/ShadowWalkerGIT/DownloadUtil.git

    使用说明:只需关注DownloadManager,这是一个单例,通过DownloadManager.getInstance()获取实例,使用前设置DownloadListener;然后调用DownloadManager.download(String cacheDir,String url)进行下载即可。注:1.不用考虑缓存目录是否存在,内部已做校验,如果不存在会自动创建该缓存目录;2.下载失败后会自动删除片段文件,不用手动清理垃圾;3.在调用的地方,比如Activity onDestroy里面调用DownloadManager.release()防止内存泄漏;4.需要的权限有网络权限和存储权限,具体代码如下:

public class DownLoadManager {
    private static DownLoadManager mDownloadManger;

    private DownLoadManager() {
    }

    public static DownLoadManager getInstance() {
        if (null == mDownloadManger) {
            synchronized (DownLoadManager.class) {
                if (null == mDownloadManger) {
                    mDownloadManger = new DownLoadManager();
                }
            }
        }
        return mDownloadManger;
    }

    /**
     * @param cacheDir
     * @param url
     */
    public void downLoad(final String cacheDir, String url) {
        if (TextUtils.isEmpty(cacheDir)) {
            if (mDownloadListener != null) {
                mDownloadListener.onDownloadError(new NullPointerException("缓存目录为空"));
            }
            return;
        }
        //缓存的key采用文件url生成的MD5
        final String cacheKey = MD5Util.stringToMD5(url);
        final String fileName = url.substring(url.lastIndexOf("/"), url.length());
        ACache aCache = ACache.get(MainApplication.getContext());
        String filePath = aCache.getAsString(cacheKey);

        if (!TextUtils.isEmpty(filePath) && new File(filePath).exists()) {//已经下载好,不用下载
            if (mDownloadListener != null) {
                mDownloadListener.onDownloadFinish(filePath);
                return;
            }
        }
        OkHttpClient okHttpClient = new OkHttpClient();
        Request.Builder builder = new Request.Builder();
        builder.url(url);
        builder.get();
        Call call = okHttpClient.newCall(builder.build());
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                try {
                    int index = fileName.lastIndexOf(".");
                    String tempFilePath = fileName;
                    if (index != -1) {
                        tempFilePath = fileName.substring(0, index);
                    }
                    File file = new File(cacheDir + "/" + tempFilePath);
                    if (file.exists()) {
                        file.delete();
                    }
                } catch (Exception exception) {
                }
                if (mDownloadListener != null) {
                    mDownloadListener.onDownloadError(e);
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                ResponseBody responseBody = ProgressHelper.withProgress(response.body(), new ProgressUIListener() {

                    //if you don't need this method, don't override this methd. It isn't an abstract method, just an empty method.
                    @Override
                    public void onUIProgressStart(long totalBytes) {
                        super.onUIProgressStart(totalBytes);
                        if (mDownloadListener != null) {
                            mDownloadListener.onDownloadStart(totalBytes);
                        }
                    }

                    @Override
                    public void onUIProgressChanged(long numBytes, long totalBytes, float percent, float speed) {
                        if (mDownloadListener != null) {
                            mDownloadListener.onDownloadProgressChange(numBytes, totalBytes, percent, speed);
                        }
                    }

                    //if you don't need this method, don't override this methd. It isn't an abstract method, just an empty method.
                    @Override
                    public void onUIProgressFinish() {
                        super.onUIProgressFinish();
                        //缓存路径
                        ACache.get(MainApplication.getContext()).put(cacheKey, cacheDir + "/" + fileName);
                        if (mDownloadListener != null) {
                            mDownloadListener.onDownloadFinish(cacheDir + "/" + fileName);
                        }
                    }
                });

                BufferedSource source = responseBody.source();
                File fileDir = new File(cacheDir);
                if (!fileDir.exists()) {
                    fileDir.mkdirs();
                }
                File outFile = new File(fileDir, fileName);
                outFile.delete();
                outFile.getParentFile().mkdirs();
                outFile.createNewFile();

                BufferedSink sink = Okio.buffer(Okio.sink(outFile));
                source.readAll(sink);
                sink.flush();
                source.close();
            }
        });
    }

    public static void release() {
        if (mDownloadManger != null) {
            mDownloadManger.mDownloadListener = null;
        }
        mDownloadManger = null;
    }

    private DownloadListener mDownloadListener;

    public void setDownloadListener(DownloadListener downloadListener) {
        this.mDownloadListener = downloadListener;
    }

    public interface DownloadListener {
        /**
         * 下载开始,在UI线程调用
         *
         * @param totalBytes
         */
        void onDownloadStart(long totalBytes);

        /**
         * 正在下载,在UI线程调用
         *
         * @param numBytes
         * @param totalBytes
         * @param percent
         * @param speed
         */
        void onDownloadProgressChange(long numBytes, long totalBytes, float percent, float speed);

        /**
         * 下载完成,在UI线程调用
         *
         * @param filePath
         */
        void onDownloadFinish(String filePath);

        /**
         * 下载失败
         *
         * @param e
         */
        void onDownloadError(Exception e);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值