图片三级缓存原理
在移动应用中,我们一般将网络图片分为三个级别,第一级别是网络层,即根据图片的url地址可以找到服务器上相应图片,获取这一层的图片会消耗流量,所以我们希望可以获取后本地就永久使用,所以就会有接下来的缓存策略;第二层缓存是在手机内存层,是将第一层的图片下载到手机内存,这种缓存读取速度非常快,但当图片内存被回收时,图片自然就不会存在了,第三层则是在手机硬盘层,是会缓存到sd卡。但这一层相对于内存的读取速度会慢很多,所以,很好的协调这三层图片缓存就可以提升应用性能和用户体验。
保存:
1.从网络下载图片
2.保存到内存中
3.保存到本地缓存文件中
获取:
1.从内存中获取图片
2.如果内存中没有图片,从本地缓存文件获取图片,在保存到内存中,为下一次显示做准备
3.如果本地缓存文件也没有图片,从网络下载图片,在保存到内存和本地缓存中
LruCache<K,V> 算法 K:图片名称类型 V:图片类型 安卓自带算法
JPEG可以设置图片质量 大小 下载缓存数据
PNG图片质量的百分比设置没效果
内存缓存图片
1.创建
private LruCache<String, Bitmap> lruCache;
public ImageCacheUtil( ){
int maxSize = (int)(Runtime.getRuntime( ).maxMemory( )/8 );
//maxSize : 缓存的最大空间,一般是内存的八分之一
lruCache = new LruCache<String, Bitmap>(maxSize){
//获取移出图片的大小
@Override
protected int sizeOf(String key, Bitmap value) {
//getRowBytes():获取图片一行占用的大小
//getHeight() : 图片占用的行数
return value.getRowBytes()*value.getHeight();
}
};
}
2.使用
保存
lruCache.put(url, bitmap);
获取
Bitmap bitmap = lruCache.get(url);
if (bitmap!=null) {
return bitmap;
}
本地缓存图片
1.缓存图片
/**
* 将图片缓存到本地
* @param url
* @param value
*/
private void setBitmapToLocal(String url,Bitmap value){
try {
//http://10.0.2.2/zhbj/photos/...jpg
File file = new File(cacheDir, MD5Util.md5(url).substring(10));
FileOutputStream outputStream = new FileOutputStream(file);
//compress : 就是将图片保存本地的操作,同时还可以设置图片的格式,质量
//format : 图片的格式
//quality : 图片的质量,百分比
//stream : 写入流
value.compress(CompressFormat.JPEG, 100, outputStream);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2.获取图片
/**
* 从本地缓存获取图片
* @param url
*/
private Bitmap getBitmapFromLocal(String url) {
try{
File file = new File(cacheDir, MD5Util.md5(url).substring(10));
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
//保存到内存中使用
lruCache.put(url, bitmap);
return bitmap;
}catch (Exception e) {
}
return null;
}
从网络下载图片
1.创建线程池
//nThreads : 线程池中线程的数量
newFixedThreadPool = Executors.newFixedThreadPool(5);
2.使用线程池
/**
* 从网络下载图片
* @param url
*/
private void getBitmapFromNet(String url) {
newFixedThreadPool.execute(new RunnableTask(url));
}
private class RunnableTask implements Runnable{
private String mUrl;
public RunnableTask(String url) {
this.mUrl = url;
}
@Override
public void run() {
try {
//根据图片的路径下载图片
URL url = new URL(mUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(5000);//连接超时时间
con.setReadTimeout(5000);//读取超时时间
InputStream stream = con.getInputStream();//获取服务器返回的数据,服务器是以流的形式返回
Bitmap bitmap = BitmapFactory.decodeStream(stream);
//将获取的图片保存到内存和本地
lruCache.put(mUrl, bitmap);
setBitmapToLocal(mUrl, bitmap);
return;//通知线程池,回收线程
} catch (Exception e) {
e.printStackTrace();
}
}
}