将LruCache+DiskLruCache+软引用三种缓存技术结合起来,加强图片的缓存效果。

import android.content.Context;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Build;import android.os.Environment;import android.support.v4.util.LruCache;import com.jakewharton.disklrucache.DiskLruCache;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.lang.ref.SoftReference;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.LinkedHashMap;public class ImageCache {    private static final String IMAGE_PATH = "image";    private static final int DEFAULT_MEM_CACHE_SIZE = 1024 * 1024 * 8;    private static final int DEFAULT_DIS_CACHE_SIZE = 1024 * 1024 * 10;    private static final int DEDAULT_SOFT_CACHE_NUM = 20;    private LruCache<String, Bitmap> mLruCache;    private DiskLruCache mDisLruCache;    private LinkedHashMap<String, SoftReference<Bitmap>> mSoftCache;    private volatile static ImageCache mImageCache;    private ImageCache(Context context) {        mLruCache = new LruCache<String,Bitmap>(DEFAULT_MEM_CACHE_SIZE) {            @Override            protected int sizeOf(String key, Bitmap value) {                return getBitmapSize(value);            }            @Override            protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {                if (evicted) {                    mSoftCache.put(key, new SoftReference<Bitmap>(oldValue));                }                super.entryRemoved(evicted, key, oldValue, newValue);            }        };        try {            mDisLruCache.open(getDiskCacheDir(context), getAppVersion(context), 1, DEFAULT_DIS_CACHE_SIZE);        } catch (IOException e) {            e.printStackTrace();        }        mSoftCache = new LinkedHashMap<String, SoftReference<Bitmap>>(                DEDAULT_SOFT_CACHE_NUM, 0.75f, true) {            private static final long serialVersionUID = 1L;            /** * 当软引用数量大于20的时候,最旧的软引用将会被从链式哈希表中移出 */            @Override            protected boolean removeEldestEntry(                    Entry<String, SoftReference<Bitmap>> eldest) {                if (size() > DEDAULT_SOFT_CACHE_NUM) {                    return true;                }                return false;            }        };    }    public static ImageCache getInstance(Context context) {        if (mImageCache == null) {            synchronized (ImageCache.class) {                if (mImageCache == null) {                    mImageCache = new ImageCache(context);                }            }        }        return mImageCache;    }    /* * 查看缓存是否存在key的图片, * 在从网络获取图片之前可以先进行查看,如果没有就网络请求 * * 策略:先查看mLruCache是否存在该实例对象,即查看内存是否存在该对象 * 再查看mSoftCache是否存在,即查看mLruCache中被回收的对象中是否存在该对象 * 最后查看Disk中是否缓存了该对象 * * */    public Bitmap get(String key) {        key = hashKey(key);        DiskLruCache.Snapshot snapshot = null;        Bitmap bitmap = mLruCache.get(key);        if (bitmap == null) {            bitmap = mSoftCache.get(key).get();            if (bitmap == null) {                if (mDisLruCache != null) {                    try {                        snapshot = mDisLruCache.get(key);                        if (snapshot != null) {                            InputStream is = snapshot.getInputStream(0);                            bitmap = BitmapFactory.decodeStream(is);                        }                    } catch (IOException e) {                        e.printStackTrace();                    }                }            } else {                mSoftCache.remove(key);            }            if (bitmap != null) {                mLruCache.put(key, bitmap);            }        }        return bitmap;    }    /* * 从网络获取到图片资源之后,就调用该方法将它进行缓存, * */    public void put(String key, Bitmap bitmap) {        key = hashKey(key);        mLruCache.put(key, bitmap);        if (mDisLruCache != null) {            try {                DiskLruCache.Editor editor = mDisLruCache.edit(key);                if (editor != null) {                    OutputStream outputStream = editor.newOutputStream(0);                    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);                    outputStream.write(byteArrayOutputStream.toByteArray());                    editor.commit();                    mDisLruCache.flush();                }            } catch (IOException e) {                e.printStackTrace();            }        }    }    /* * 获取图片大小 * */    private int getBitmapSize(Bitmap bitmap) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {            return bitmap.getByteCount();        }        return bitmap.getRowBytes() * bitmap.getHeight();    }    /* * 得到Disk缓存目标 * */    private File getDiskCacheDir(Context context) {        String cachePath;        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {            cachePath = context.getExternalCacheDir().getPath();        } else {            cachePath = context.getCacheDir().getPath();        }        return new File(cachePath + File.separator + IMAGE_PATH);    }    /* * 获取应用版本号 * */    private int getAppVersion(Context context) {        try {            PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(),0);            return info.versionCode;        } catch (PackageManager.NameNotFoundException e) {            e.printStackTrace();        }        return 1;    }    /* * 将key编码为MD5 * */    private String hashKey(String key) {        String cacheKey;        MessageDigest digest = null;        try {            digest = MessageDigest.getInstance("MD5");            digest.update(key.getBytes());            cacheKey = bytesToHexString(digest.digest());        } catch (NoSuchAlgorithmException e) {            cacheKey = String.valueOf(key.hashCode());            e.printStackTrace();        }        return cacheKey;    }    private String bytesToHexString(byte[] bytes) {        StringBuilder sb = new StringBuilder();        for (int i = 0; i < bytes.length; i++) {            String hex = Integer.toHexString(0xFF & bytes[i]);            if (hex.length() == 1) {                sb.append('0');            }            sb.append(hex);        }        return sb.toString();    }}

参考文章:
Android图片缓存技术

android中图片的三级cache策略(内存、文件、网络)之二:内存缓存策略

更多相关文章

  1. Android(安卓)分别使用Post与Get实现网络图片加载
  2. Android文件图片上传的详细讲解(三)---模式回调类
  3. android保存图片到图库
  4. Android(安卓)批量读取APK 包名,版本信息
  5. Android源代码查看途径
  6. Android使用AsyncTask下载图片并显示进度条功能
  7. android 从sdcard 读取图片 剪切 粘贴
  8. Android选择与上传图片之ImagePicker教程
  9. android自定义Toast视图

随机推荐

  1. Android 代码实现的动画
  2. eclipse 项目导入 android studio的方式
  3. Android 通过HTTP POST 上传图片文件
  4. Android Room 数据库
  5. android抓log方法
  6. Android ToastUtils,吐司工具类
  7. 布局概述之帧布局FrameLayout和布局概述
  8. Android 中 上下文Context理解
  9. Android 获取手机本地IP
  10. Android 发送短信功能