android LruCache的使用 (本地缓存+内存缓存)
16lz
2021-01-26
package com.example.redbaby.utils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
import android.util.LruCache;
/**
* 实现系统的LRCCACHE的子类 用于本地缓存图片 当内存中的缓存超过阀值就会去删除连标的最前边那个(访问最少的) 而且会调用
* entryRemoved()方法 这个方法实际上什么都没有做 这里我们来实现它 将删除的图片保存在本地
*
* create方法呢 是在调用lrucache的get方法时如果内存中没有该key对应的value 那么就会调用create方法
* create方法也是什么没做 这里我们来实现它从文件系统取出数据
*
* @author s0ng
*
* @param
* @param
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public class MyLruCache extends LruCache {
private long local_Size;
private File file;
private long freeSize;
private static final long NOT_LOCAL_CACHE_SIZE = 50 * 1024 * 1024;
public MyLruCache(int maxSize, long local_Size, String file_path) {
super(maxSize);
this.local_Size = local_Size;
file = new File(file_path);
if (file.exists()) {
if (!file.isDirectory()) {
throw new IllegalArgumentException("maxSize <= 0");
}
} else {
file.mkdirs();
}
freeSize = freeSpaceOnSd();
}
@Override
protected Bitmap create(String key) {
// 这里从我们的文件系统中找到
key = key.replace("/", "杠");
key = key.replace(":", "冒");
String path = file.getAbsolutePath() + "/" + key;
return BitmapFactory.decodeFile(path);
}
/**
* 这里讲value添加到我们的 文件系统 但是必须保证 如果文件的内容超出 缓存指定大小
*/
@Override
protected void entryRemoved(boolean evicted, String key, Bitmap oldValue,
Bitmap newValue) {
/**
* 如果开启本应用的时候内存小于50M 我们就不要本地缓存了
*
*/
if (NOT_LOCAL_CACHE_SIZE > freeSize) {
return;
}
key = key.replace("/", "杠");
key = key.replace(":", "冒");
File bm = (new File(file, key));
if (bm.exists()) {
return;
}
try {
bm.createNewFile();
OutputStream outStream = new FileOutputStream(bm);
oldValue.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
Log.w("ImageFileCache", "FileNotFoundException");
} catch (IOException e) {
e.printStackTrace();
Log.w("ImageFileCache", "IOException");
}
}
private int freeSpaceOnSd() {
StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
.getPath());
double sdFree = ((double) stat.getAvailableBlocks() * (double) stat
.getBlockSize());
return (int) sdFree;
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
import android.util.LruCache;
/**
* 实现系统的LRCCACHE的子类 用于本地缓存图片 当内存中的缓存超过阀值就会去删除连标的最前边那个(访问最少的) 而且会调用
* entryRemoved()方法 这个方法实际上什么都没有做 这里我们来实现它 将删除的图片保存在本地
*
* create方法呢 是在调用lrucache的get方法时如果内存中没有该key对应的value 那么就会调用create方法
* create方法也是什么没做 这里我们来实现它从文件系统取出数据
*
* @author s0ng
*
* @param
* @param
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public class MyLruCache extends LruCache
private long local_Size;
private File file;
private long freeSize;
private static final long NOT_LOCAL_CACHE_SIZE = 50 * 1024 * 1024;
public MyLruCache(int maxSize, long local_Size, String file_path) {
super(maxSize);
this.local_Size = local_Size;
file = new File(file_path);
if (file.exists()) {
if (!file.isDirectory()) {
throw new IllegalArgumentException("maxSize <= 0");
}
} else {
file.mkdirs();
}
freeSize = freeSpaceOnSd();
}
@Override
protected Bitmap create(String key) {
// 这里从我们的文件系统中找到
key = key.replace("/", "杠");
key = key.replace(":", "冒");
String path = file.getAbsolutePath() + "/" + key;
return BitmapFactory.decodeFile(path);
}
/**
* 这里讲value添加到我们的 文件系统 但是必须保证 如果文件的内容超出 缓存指定大小
*/
@Override
protected void entryRemoved(boolean evicted, String key, Bitmap oldValue,
Bitmap newValue) {
/**
* 如果开启本应用的时候内存小于50M 我们就不要本地缓存了
*
*/
if (NOT_LOCAL_CACHE_SIZE > freeSize) {
return;
}
key = key.replace("/", "杠");
key = key.replace(":", "冒");
File bm = (new File(file, key));
if (bm.exists()) {
return;
}
try {
bm.createNewFile();
OutputStream outStream = new FileOutputStream(bm);
oldValue.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
Log.w("ImageFileCache", "FileNotFoundException");
} catch (IOException e) {
e.printStackTrace();
Log.w("ImageFileCache", "IOException");
}
}
private int freeSpaceOnSd() {
StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
.getPath());
double sdFree = ((double) stat.getAvailableBlocks() * (double) stat
.getBlockSize());
return (int) sdFree;
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
}
就是这么简单 不用双缓存 另外 还以一给缓存本地文件设置个大小上线 并且本人还是很有良知的 剩余sd卡内存小于50M的时候我们就不往本地存储卡写数据了
更多相关文章
- Android(安卓)倒计时功能的实现(CountDownTimer)
- 圆角ImageView的几种实现方法
- Android(安卓)内部存储外部存储
- 万能 dao 增删改查一个方法搞定
- Glide源码浅析
- dagger.android 源码
- Fragment.setArguments()方法向fragment对象传递数据的重要作用
- Android(安卓)图片内存缓存
- OpenGl-ES2.0 For Android(安卓)读书笔记(一)