Android 本地圖片緩存

廢話

每次從內存裏面讀圖片,圖片小的話還好,圖片大的話比較吃力,速度慢不說,還容易由於內存問題出現崩潰。java

後來加上了緩存,從緩存中讀取,結果發現,仍是會爆炸,檢查一下發現,一張拍照3M多,直接把整個緩存區都炸開了,既然找到問題了,也就好解決了。android

因此就加上了個壓縮,邏輯是:1-從緩存中讀取 2-讀取不到,先從內存中讀取,同時異步壓縮圖片 3-壓縮完成以後寫入緩存 4-再次讀取能夠在緩存中找到git

工具

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

(圖片壓縮)魯班壓縮: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;
    }

}

調用:app

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

相關文章
相關標籤/搜索