Android图片三级缓存策略图片三级缓存策略(网络、本地、内存缓存网络、本地、内存缓存)
一、简介一、简介
现在的Android应用程序中,不可避免的都会使用到图片,如果每次加载图片的时候都要从网络重新拉取,这样不但很耗费用
户的流量,而且图片加载的也会很慢,用户体验很不好。所以一个应用的图片缓存策略是很重要的。通常情况下,Android应
用程序中图片的缓存策略采用“内存-本地-网络”三级缓存策略,首先应用程序访问网络拉取图片,分别将加载的图片保存在本
地SD卡中和内存中,当程序再一次需要加载图片的时候,先判断内存中是否有缓存,有则直接从内存中拉取,否则查看本地
SD卡中是否有缓存,SD卡中如果存在缓存,则图片从SD卡中拉取,否则从网络加载图片。依据这三级缓存机制,可以让我
们的应用程序在加载图片的时候做到游刃有余,有效的避免内存溢出。
PS:当然现在处理网络图片的时候,一般人都会选择XUtils中的BitmapUtil,它已经将网络缓存处理的相当好了,使用起来非
常方便–本人就一直在用。仿照BitMapUtil的实现思路,定制一个自己的图片加载工具,来理解一下三级缓存的策略,希望对
自己会有一个提升。
二、网络缓存二、网络缓存
网络拉取图片严格来讲不能称之为缓存,实质上就是下载url对应的图片,我们这里姑且把它看作是缓存的一种。仿照
BitmapUtil中的display方法,我自己定制的CustomBitmapUtils也定义这个方法,根据传入的url,将图片设置到ivPic控件上。
public void display(ImageView ivPic, String url) {
}
定义网络缓存的工具类,在访问网络的时候,我使用了AsyncTask来实现,在AsyncTask的doInBackGround方法里下载图
片,然后将 图片设置给ivPic控件,AsyncTask有三个泛型,其中第一个泛型是执行异步任务的时候,通过execute传过来的参
数,第二个泛型是更新的进度,第三个泛型是异步任务执行完成之后,返回来的结果,我们这里返回一个Bitmap。具体的下
载实现代码如下:
/** * 网络缓存的工具类 * * @author ZHY * */ public class NetCacheUtils
{ private LocalCacheUtils localCacheUtils;
private MemoryCacheUtils memoryCacheUtils;
public NetCacheUtils()
{
localCacheUtils = new LocalCacheUtils();
memoryCacheUtils = new MemoryCacheUtils();
}
/** * 从网络下载图片 *
* @param ivPic *
@param url */
public void getBitmapFromNet(ImageView ivPic, String url)
{
// 访问网络的操作一定要在子线程中进行,采用异步任务实现 MyAsyncTask task = new MyAsyncTask(); task.execute(ivPic, url); }
/** * 第一个泛型--异步任务执行的时候,通过execute传过来的参数;
第二个泛型--更新进度; 第三个泛型--异步任务执行以后返回的结果
* * @author ZHY * */
private class MyAsyncTask extends AsyncTask
{ private ImageView ivPic; private String url; // 耗时任务执行之前
--主线程
@Override protected void onPreExecute()
{ super.onPreExecute();
}
// 后台执行的任务
@Override protected Bitmap doInBackground(Object... params)
{
// 执行异步任务的时候,将URL传过来 ivPic = (ImageView) params[0]; url = (String) params[1]; Bitmap bitmap = downloadBitmap(url);
// 为了保证ImageView控件和URL一一对应,给ImageView设定一个标记 ivPic.setTag(url);
// 关联ivPic和URL return bitmap; }
// 更新进度 --主线程
@Override protected void onProgressUpdate(Void... values)
{ super.onProgressUpdate(values);
}
// 耗时任务执行之后--主线程
@Override protected void onPostExecute(Bitmap result)
{ String mCurrentUrl = (String) ivPic.getTag();
if (url.equals(mCurrentUrl))
{ ivPic.setImageBitmap(result);
System.out.println("从网络获取图片");
// 从网络加载完之后,将图片保存到本地SD卡一份,保存到内存中一份
localCacheUtils.setBitmap2Local(url, result);
// 从网络加载完之后,将图片保存到本地SD卡一份,保存到内存中一份 memoryCacheUtils.setBitmap2Memory(url, result);
} } }
/** * 下载网络图片 *
* @param url * @return */
private Bitmap downloadBitmap(String url)