将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文件图片上传的详细讲解(三)---模式回调类
  2. android保存图片到图库
  3. Android的GridView控件点击图片变暗效果
  4. Android 分别使用Post与Get实现网络图片加载
  5. android 从sdcard 读取图片 剪切 粘贴
  6. Android使用AsyncTask下载图片并显示进度条功能
  7. Android 部分内容设置颜色、字体、超链接、图片
  8. (Android)处理图片成圆形
  9. MixtureTextView 支持Android图文混排、文字环绕图片等效果

随机推荐

  1. android 百度地图定位代码参考
  2. android C/C++ source files 全局宏定义
  3. Android(安卓)滑动渐变 扩展效果 免费专
  4. Android(安卓)API Level 与 Platform Ver
  5. Android: Transferring Data Without Dra
  6. [Android] 零碎知识汇总 - RecyclerView
  7. android in practice_Communicating chan
  8. 模拟抽奖的九宫格动画效果
  9. Android学习之使用HttpURLConnection下载
  10. Tips for Designers: from a Developer[S