思路:根据图片的URL地址加载图片
if(图片存在于内存中) {
return;
} else {
if(图片存在于文件缓存中) {
return;
} else {
开启线程去加载图片
}
}
大致的思路是这样,接下就是具体实现。使用LruCache 覆盖entryRemoved方法,把最不常用的删除后在把新获取的put进去。
private int memorySize = 2 * 1024 * 1024;
private int fileSize = 20 * 1024 * 1024; //20M的文件缓存
private File fileDir = null;
private LruCache<String, Bitmap> memoryCache;
private LruCache<String, Long> fileCache = new LruCache<String, Long>(
fileSize) {
@Override
public int sizeOf(String key, Long value) {
return value.intValue();
}
@Override
protected void entryRemoved(boolean evicted, String key, Long oldValue,
Long newValue) {
try {
File file = getFile(key);
if (file != null) {
file.delete();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
};
private static BitmapCaches instance = null;
public static synchronized BitmapCaches getInstance(Context context) {
if (null == instance) {
instance = new BitmapCaches(context);
}
return instance;
}
public BitmapCaches(Context context) {
// 使用 25% 的内存作为内存存储
memorySize = (int) (Runtime.getRuntime().maxMemory() / 4);
memoryCache = new LruCache<String, Bitmap>(memorySize) {
private String last_key = "";
@Override
protected int sizeOf(String key, Bitmap bitmap) {
last_key = key;
int size = bitmap.getHeight() * bitmap.getWidth() * 2;
return size;
}
@Override
protected void entryRemoved(boolean evicted, String key,
Bitmap oldBitmap, Bitmap newBitmap) {
// 移到文件缓存
addFile(key, oldBitmap);
if (!key.equalsIgnoreCase(last_key)) {
oldBitmap.recycle();
oldBitmap = null;
System.gc();
}
}
};
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED))
fileDir = new File(App.path_bitmap);
else
fileDir = context.getCacheDir();
if (!fileDir.exists())
fileDir.mkdirs();
}
public Bitmap get(String url) {
Log.e("BitmapCaches", url);
String key = StringUtil.getMD5(url.getBytes());
// 从内存中取
synchronized (memoryCache) {
Bitmap bitmap = memoryCache.get(key);
if (bitmap != null) {
if (bitmap.isRecycled()) {
memoryCache.remove(key);
return null;
}
return bitmap;
}
}
// 从文件中取
synchronized (fileCache) {
try {
File file = getFile(key);
if (file != null) {
Bitmap bitmap = ImageUtil.decodeFile(file);
if (bitmap != null) {
if (bitmap.isRecycled()) {
return null;
} else {
synchronized (memoryCache) {
memoryCache.put(key, bitmap);
}
return bitmap;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
public void put(String url, Bitmap bitmap) {
String key = StringUtil.getMD5(url.getBytes());
if (key != null && bitmap != null) {
synchronized (memoryCache) {
Log.w("Bitmpa Cache", "add cache: " + key);
memoryCache.put(key, bitmap);
}
}
}
public void clear() {
if (memoryCache != null) {
memoryCache.evictAll();
}
if (fileCache != null) {
fileCache.evictAll();
}
if (fileDir == null)
return;
File[] files = fileDir.listFiles();
if (files != null) {
for (File f : files)
f.delete();
}
System.gc();
}
private File getFile(String key) throws FileNotFoundException {
if (fileDir == null)
return null;
File file = new File(fileDir, key);
if (!file.exists() || !file.isFile())
return null;
return file;
}
private void addFile(String key, Bitmap bitmap) {
try {
File file = getFile(key);
if (file != null) {
Log.w("Bitmpa Cache", "add file err: existed");
return;
}
FileOutputStream fos = getOutputStream(key);
if (fos != null) {
boolean saved = bitmap.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
if (saved) {
synchronized (fileCache) {
Log.w("Bitmpa Cache", "add file: " + key);
fileCache.put(key, getFile(key).length());
}
} else {
Log.w("Bitmpa Cache", "add file err: saved error");
}
} else {
Log.w("Bitmpa Cache", "add file err: FileOutputStream null");
}
} catch (Exception e) {
e.printStackTrace();
}
}
private FileOutputStream getOutputStream(String key) {
if (fileDir == null)
return null;
try {
FileOutputStream fos = new FileOutputStream(
fileDir.getAbsolutePath() + File.separator + key);
return fos;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
使用方法:
Caches是上面的类。
Bitmap bitmap = Caches.getInstance(context).get('图片URL地址');
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
开启线程去加载图片
图片加载出来之后增加Caches.getInstance(context).put(url, bitmap);
}
decodeFile()这个方法是把File转换为Bitmap
太囧笑话网