将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. 华清远见免费博文
  2. Android 实现下载时主界面与详细界面一致
  3. Android 使用HttpClient方式提交POST请求
  4. android 文件的读取与写入以及TextView的
  5. android判断网络的状态断开与否
  6. android 照片旋转并保存
  7. java(Android)——内存泄露的一些经典案
  8. android之获取当前日期所属的本周、本月
  9. Android两种轮询的实现方法
  10. Android 增加LOG