Android网络请求图片缓存本地无OOM支持安卓7.0

Android网络请求图片缓存本地无OOM支持安卓7.0

在开发中经常遇到异步网络请求图片,为了节约流量经常需要把图片存放在本地文件夹,下次请求直接读取文件夹下面图片。但有可能图片太大造成内存溢出(OOM)。为了解决这些问题专门写了一个类来做这些事情。代码注释十分详细。

1.网络连接采用import java.net.URLConnection;更加快速,更加稳定
2.引入线程池管理
3.图片存放本地,下次访问快速
4.防止OOM【再多再大图片无压力】
5.使用简单方便
6.可直接拖放到工程使用,很稳定

点击这儿下载源代码JAVA类。

1. 设置图片方法举例:

//高清4K
String url="http://attach.bbs.miui.com/forum/201502/03/150905vpzrbnzksnkbkyhr.jpg";
YnetImg yset=new YnetImg(getApplicationContext());
//路径,imageView,清除错误时候默认加载的图片
yset.set(url, imageView, R.drawable.a);

2. 清除本地缓存:

YnetImg img=new YnetImg(getApplicationContext());
img.clearCache();
  • -

3.关键代码

  1. 关键变量
// 硬引用缓存缓存Bitmap
private static LruCache<String, Bitmap> bitMapLruCache; 
// 硬引用缓存存请求队列
private static LruCache<String, String> imageViewCache; 
// 记录全部下载任务
downloads = new ArrayList<FileDownloadThread>();
/** 线程队列同时最多运行10个 */
private static ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(10);
  1. 网络请求,如果缓存有图片直接设置给imageView,缓存没有就本地找,本地没有就网络下载到本地然后设置给imageView,并且记录给缓存
/**
     * @Title: set
     * @Description: TODO(网络请求,如果缓存有图片直接设置给imageView,缓存没有就本地找,本地没有就网络下载到本地然后设置给imageView,并且记录给缓存)
     * @param url
     *            下载路径
     * @param imageView
     *            要设置的imageView
     * @param defaultImage
     *            出错时显示的defaultImage
     * @return void 返回类型
     */
    public void set(final String url, final ImageView imageView,
            final int defaultImage) {
        // 用户传递空值直接拒绝继续执行
        if (url == null || imageView == null || defaultImage == 0)
            return;
        if (bitMapLruCache.get(url) != null) {// 先在缓存中找图片
            imageView.setImageBitmap(bitMapLruCache.get(url));// 显示
            return;
        }
        // 判断该imageView是否正在请求该网络,若是则不请求
        if (imageViewCache.get(url + imageView.toString()) != null
                && (url + imageView.toString()).equals(imageViewCache.get(url
                        + imageView.toString()))) {// 先在缓存中找图片
            return;
        }
        imageViewCache.put(url + imageView.toString(),
                url + imageView.toString());
        // 给保存文件命名
        String fileName = MD5Util.MD5(url) + getLastName(url);
        // 开始请求网络
        YDownload download = new YDownload(url, path, fileName,
                new YDownloadImgListener() {
                    @Override
                    public void response(boolean issuccess, String url,
                            String path, String fileName) {
                        // 请求回调结果
                        imageViewCache.remove(url + imageView.toString());// 在请求队列中把删除
                        // 请求是否成功
                        if (issuccess) {
                            // 这样要内存溢出
                            // Bitmap bitmap =
                            // BitmapFactory.decodeFile(path+"/"+ fileName);
                            // 这样可以防止内存溢出
                            Bitmap bitmap = BitmapFactory.decodeByteArray(
                                    BitmapMemory.decodeBitmap(path + "/"
                                            + fileName),
                                    0,
                                    BitmapMemory.decodeBitmap(path + "/"
                                            + fileName).length);
                            if (bitmap == null) {
                                Log.e("错误", "读取的文件不能转换成bitmap");
                                Bitmap bmp = BitmapFactory.decodeResource(
                                        context.getResources(), defaultImage);
                                imageView.setImageBitmap(bmp);// 显示默认图片
                                return;
                            }
                            bitMapLruCache.put(url, bitmap);// 把bitmap添加保存起来
                            imageView.setImageBitmap(bitmap);// 显示
                        } else {
                            // 把资源文件转换成bitmap
                            Bitmap bmp = BitmapFactory.decodeResource(
                                    context.getResources(), defaultImage);
                            imageView.setImageBitmap(bmp);// 显示默认图片
                        }
                    }
                });
        download.setDiskCache(true);// 是否开启缓存
        download.setTimeOut(8000);// 设置延迟
        download.start();// 开始,将开启一个线程丢入线程队列
    }
  1. 初始化缓存
    /**
     * 初始化缓存
     */
    private void setImageCache() {
        if (bitMapLruCache == null) {
            int memClass = (((ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE)))
                    .getMemoryClass();
            int cacheSize = 1024 * 1024 * memClass / 10; // 硬引用缓存容量,为系统可用内存的1/10
            bitMapLruCache = new LruCache<String, Bitmap>(cacheSize) {
                @SuppressLint("NewApi")
                @Override
                protected int sizeOf(String key, Bitmap bitmap) {
                    if (bitmap != null) {// 返回bitmap大小
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// API
                                                                                    // 19
                            return bitmap.getAllocationByteCount();
                        }
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {// API
                                                                                            // 12
                            return bitmap.getByteCount();
                        }
                        return bitmap.getRowBytes() * bitmap.getHeight(); // earlierversion
                    } else
                        return 0;
                }
            };
        }
        if (imageViewCache == null) {
            int memClass = (((ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE)))
                    .getMemoryClass();
            int cacheSize = 1024 * 1024 * memClass / 10; // 硬引用缓存容量,为系统可用内存的1/10
            imageViewCache = new LruCache<String, String>(cacheSize);
        }
    }

希望大家多多提出意见一起努力进步。
点击这儿下载源代码JAVA类。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值