Android 本地图片缓存

废话

每次从内存里面读图片,图片小的话还好,图片大的话比较吃力,速度慢不说,还容易因为内存问题出现崩溃。

后来加上了缓存,从缓存中读取,结果发现,还是会爆炸,检查一下发现,一张拍照3M多,直接把整个缓存区都炸开了,既然找到问题了,也就好解决了。

所以就加上了个压缩,逻辑是:1-从缓存中读取 2-读取不到,先从内存中读取,同时异步压缩图片 3-压缩完成之后写入缓存 4-再次读取可以在缓存中找到

工具

(缓存工具)Lrucache:https://blog.csdn.net/jxxfzgy/article/details/44885623

(图片压缩)鲁班压缩:https://github.com/Curzibn/Luban

代码


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.LruCache;

import java.io.File;

import top.zibin.luban.CompressionPredicate;
import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;

/**
 * 图片缓存类(仅供缓存本地图片使用)
 */
public class LruCacheUtils {
    private static LruCache<String, Bitmap> mMemoryCache;

    /**
     * 初始化(必须),推荐在Application中启动,一次就可以了
     */
    public static void init() {
        int maxMemory = (int) (Runtime.getRuntime().maxMemory());
        // 使用最大可用内存值的1/8作为缓存的大小。
        int cacheSize = maxMemory / 8;
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            protected int sizeOf(String key, Bitmap bitmap) {
                //在每次存入缓存的时候调用
                return bitmap.getByteCount() / 1024;
            }
        };
    }

    /**
     * 将bitmap加入到缓存中
     *
     * @param path   LruCache的键,即图片的下载路径
     * @param bitmap LruCache的值,即图片的Bitmap对象
     */
    public static void addImage(String path, Bitmap bitmap) {
        if (mMemoryCache.get(path) == null) {
            mMemoryCache.put(path, bitmap);
        }
    }

    /**
     * 读取缓存中的图片,不需要压缩
     *
     * @param path
     * @return
     */
    public static Bitmap getImage(String path) {
        Bitmap bitmap = mMemoryCache.get(path);
        if (bitmap != null) {
            return bitmap;
        }
        bitmap = BitmapFactory.decodeFile(path);
        if (bitmap != null) {
            addImage(path, bitmap);
        }
        return bitmap;
    }

    /**
     * 读取缓存中的图片,需要压缩
     *
     * @param path
     * @return
     */
    public static Bitmap getImage(Context context, final String path) {
        Bitmap bitmap = mMemoryCache.get(path);
        if (bitmap != null) {
            //充缓存里面读取
            return bitmap;
        }
        //缓存里面还没有
        bitmap = BitmapFactory.decodeFile(path);//直接从文件中读取Bitmap出来
        if (bitmap != null) {
            String cachePath = PathUtils.getImgCache();//压缩之后的文件存放的文件夹,自己设置
            Luban.with(context)
                    .load(path)
                    .ignoreBy(288)//不压缩的阈值,单位为K
                    .setTargetDir(cachePath)
                    .filter(new CompressionPredicate() {
                        @Override
                        public boolean apply(String path) {
                            return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
                        }
                    })
                    .setCompressListener(new OnCompressListener() {
                        @Override
                        public void onStart() {
                            // TODO 压缩开始前调用,可以在方法内启动 loading UI
                        }

                        @Override
                        public void onSuccess(File file) {
                            // TODO 压缩成功后调用,返回压缩后的图片文件
                            Bitmap bitmap1 = BitmapFactory.decodeFile(file.getPath());
//                            ALog.e("压缩成功:" + file.length());
                            addImage(path, bitmap1);
                            MyFileUtils.deleteFile(file);//已经缓存完成了,删除压缩好的文件
                        }

                        @Override
                        public void onError(Throwable e) {
                            // TODO 当压缩过程出现问题时调用
//                            ALog.e("压缩出错:" + e.toString());
                            addImage(path, BitmapFactory.decodeFile(path));//压缩失败,直接缓存(很少出现)
                        }
                    }).launch();
        }
        return bitmap;
    }

}

调用:

Bitmap bitmap=LruCacheUtils.getImage(getContext(),path);

猜你喜欢

转载自my.oschina.net/u/1462828/blog/2055541