下载工具类(带缓存)

原创 2018年04月17日 17:35:56
    前言:由于项目里面经常需要用到下载,所以封装了一个下载工具类。
    实现方案: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);
    }
}

实战COM(03)----创建一个进程外组件

 本文欢迎转载,唯请注明出处及作者 blackcolor@263.net---------------------------------------------------             ...
  • blackcolor
  • blackcolor
  • 2001-07-24 15:14:00
  • 1453

缓存工具类MyCacheUtil

MyCacheUtil.java package com.sunrise.jop.common.util; import java.io.File; import java.sql.Timestam...
  • jianfpeng241241
  • jianfpeng241241
  • 2016-10-27 11:24:21
  • 423

java CacheProxy 缓存工具类

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。 1.缓存代理类CacheProxy packag...
  • w410589502
  • w410589502
  • 2016-07-25 11:29:08
  • 1813

Android-网络图片下载工具类-三级缓存

新手刚学Android没多久,对于Android中读取网络图片也是刚刚接触,读取网络图片,在Android应用中经常可见,在ListView、GridView这些控件中尤其可见。而为了提高用户体验,这...
  • z82367825
  • z82367825
  • 2015-06-15 22:49:28
  • 1559

工具类:ehCache,用于缓存

准备工作: 1.导入依赖:2.6.9 2.0.4 net.sf.ehcache ehcache-core ${ehcache.version} net.s...
  • qq_34590943
  • qq_34590943
  • 2016-09-16 17:09:54
  • 678

15.缓存工具类ACache的使用

缓存工具类Acache的使用
  • qq_31715429
  • qq_31715429
  • 2016-03-25 10:53:54
  • 713

CacheMap缓存工具类

  • 2017年11月06日 16:12
  • 2KB
  • 下载

android 缓存工具类

先不废话 上工具类的源代码:Achche.java 自己拷贝到util里就好package com.eagersoft.youzy.expert.util;import android.conte...
  • u012372351
  • u012372351
  • 2016-01-22 10:41:23
  • 1469

Java - Map本地缓存工具类

这两天无意之中接触到了进程内缓存这个概念,很是开心(原谅我是一个刚入行的小白),在我的知识储备中,缓存的概念只有redis作为缓存工具.所以说路漫漫其修远兮,不是没有道理的. 什么是进程内缓存呢?根...
  • qq_15302415
  • qq_15302415
  • 2017-10-27 11:00:03
  • 107

缓存统一管理工具类--android

import android.content.Context; import android.os.Environment; import android.support.annotation.Nul...
  • lonewolf521125
  • lonewolf521125
  • 2015-07-22 15:40:41
  • 1848
收藏助手
不良信息举报
您举报文章:下载工具类(带缓存)
举报原因:
原因补充:

(最多只允许输入30个字)