之前被人问及过,图片的三级缓存是什么啊,来给我讲讲,图片三级缓存,好高大尚的名字,听着挺厉害,应该是很厉害的技术,当时不会啊,也就没什么了,没有说出来呗,前一阶端用到了BitmapUtils的图片缓存框架,索性就自己找些知识点来研究一些图片的三级缓存是什么吧。真所谓是知识你要是不知道,那就真的说不出所以然来,但是当你真正的去了解了,三级缓存也不是那么高端的技术。好了,闲话不多说了,开始图片的三级缓存原理吧。
什么是图片的三级缓存
- 1、内存缓存 优先加载,速度最快
- 2、本地缓存 次优先加载 速度稍快
- 3、网络缓存 最后加载 速度由网络速度决定(浪费流量)
图片的三级缓存图形解释
好了,既然知道了什么三级缓存的字面意思了,那么我们就来处理吧。
图片缓存—内存缓存的原理
MemoryCacheUtils.java:
package com.example.bitmaputils.bitmap;
import android.graphics.Bitmap;
import android.util.Log;
import android.util.LruCache;
/**
* 内存缓存
*/
public class MemoryCacheUtils {
/**
* LinkedHashMap<>(10,0.75f,true);
* <p/>
* 10是最大致 0.75f是加载因子 true是访问排序 false插入排序
*
*
*/
//private LinkedHashMap<String,Bitmap> mMemoryCache = new LinkedHashMap<>(5,0.75f,true);
private LruCache<String, Bitmap> mLruCache;
public MemoryCacheUtils() {
long maxMemory = Runtime.getRuntime().maxMemory();//最大内存 默认是16兆 运行时候的
mLruCache = new LruCache<String, Bitmap>((int) (maxMemory / 8)) {
@Override
protected int sizeOf(String key, Bitmap value) {
//int byteCount = value.getByteCount();
//得到图片字节数
// @return number of bytes between rows of the native bitmap pixels.
int byteCount = value.getRowBytes() * value.getWidth();
return byteCount;
}
};
}
/**
* 从内存中读取
*
* @param url
*/
public Bitmap getFromMemroy(String url) {
Log.d("MyBitmapUtils", "从内存中加载图片");
return mLruCache.get(url);
}
/**
* 写入到内存中
*
* @param url
* @param bitmap
*/
public void setToMemory(String url, Bitmap bitmap) {
mLruCache.put(url, bitmap);
}
}
很简单吧,在这里我们使用了LruCache(),对图片进行了内存缓存,这里我们只是稍微进行了处理,在这里我们只是介绍原理,当然了哈,性能,OOM溢出问题我们在这里不作处理。
图片缓存—本地缓存
package com.example.bitmaputils.bitmap;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;
import com.example.bitmaputils.MD5Encoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
* 本地缓存
*/
public class SDcardCacheUtils {
/**
* 我们读取内存的绝对路径
*/
public static final String CACHE_PATH = Environment
.getExternalStorageDirectory().getAbsolutePath() + "/aixuexi";
/**
* 从本地读取
* @param url
*/
public Bitmap getFromSd(String url){
String fileName = null;
try {
//得到图片的url的md5的文件名
fileName = MD5Encoder.encode(url);
} catch (Exception e) {
e.printStackTrace();
}
File file = new File(CACHE_PATH,fileName);
//如果存在,就通过bitmap工厂,返回的bitma