首页 > 学院 > 开发设计 > 正文

图片的三级缓存

2019-11-09 16:47:35
字体:
来源:转载
供稿:网友

三级缓存基本原理

内存缓存:速度很快,不浪费流量,优先本地缓存:速度快,不浪费流量,其次网络缓存:速度慢,浪费流量,最后

网络缓存

思路:

从网络下载图片,通过AsyncTask开启线程,创建HttpURLConnection对象,把输入流转成Bitmap

因为ListView图片错乱问题,需要给ImageView设置的Tag是图片的url链接,展示图片的时候,比较tag和url是否相等

代码:/** * 网络缓存工具类 */public class NetCacheUtils { PRivate static final String TAG = "NetCacheUtils"; public void getBitmapFromNet(ImageView imageView, String url) { //异步下载图片 new BitmapTask(imageView, url).execute(imageView, url); } class BitmapTask extends AsyncTask<Object, Void, Bitmap> { private ImageView imageView; private String url; public BitmapTask(ImageView imageView, String url) { this.imageView = imageView; this.url = url; this.imageView.setTag(this.url); } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Bitmap doInBackground(Object... params) { //使用url下载图片 Bitmap bitmap = download(url); return bitmap; } @Override protected void onPostExecute(Bitmap result) { //给ImageView设置图片 //由于ListView的重用机制, // 导致某个item有可能展示它所重用的那个item的图片,导致图片错乱 //解决方案:确保当前设置的图片和当前显示的imageView完全匹配 if (result != null) { String url = (String) imageView.getTag(); //判断当前下载的图片的url是否和ImageView的url一致,如果一致,说明完全匹配 if (this.url.equals(url)) { imageView.setImageBitmap(result); Log.i(TAG, "onPostExecute: 从网络上下载图片啦"); } } } } //下载图片 private Bitmap download(String url) { HttpURLConnection conn = null; try { conn = (HttpURLConnection) new URL(url).openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(6000);//设置连接超时 conn.setReadTimeout(6000);//设置读取超时 conn.connect();//连接 int responseCode = conn.getResponseCode();//获取返回码 if (responseCode == 200) { InputStream in = conn.getInputStream();//获取输入流 //使用输入流生成Bitmap对象 Bitmap bitmap = BitmapFactory.decodeStream(in); return bitmap; } } catch (Exception e) { e.printStackTrace(); }finally { if (conn != null) { conn.disconnect(); } } return null; }}

本地缓存

思路:

创建本地缓存工具,首先创建缓存目录,图片url通过md5加密作为文件名从网络下载图片后,保存图片到本地展示图片时,首先根据url判断本地是否有缓存,如果有就读取本地缓存,没有就从网上下载

代码: /** * 本地缓存工具类 */ public class LocalCacheUtils { //缓存文件夹 private String PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + “/zhbj_cache/”;

//写缓存 public void setLocalCache(String url, Bitmap bitmap) { //将图片保存在本地文件中 File dir = new File(PATH); if (!dir.exists() || !dir.isDirectory()) { dir.mkdirs();//创建文件夹 } try { File cacheFile = new File(dir, MD5Encoder.encode(url)); //将图片压缩保存到本地,参数1:图片的格式,参数2:压缩比(0-100), 参数3:输出流 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(cacheFile)); } catch (Exception e) { e.printStackTrace(); } } //读缓存 public Bitmap getLocalCache(String url) { try { File cacheFile = new File(PATH, MD5Encoder.encode(url)); if (cacheFile.exists()) { //缓存存在 Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(cacheFile)); return bitmap; } } catch (Exception e) { e.printStackTrace(); } return null; } }

内存缓存

思路:

创建HashMap,key是url,value是Bitmap从网络下载图片展示后,把bitmap存放到HashMap中,从本地缓存中读取图片展示后,把bitmap存放到HashMap中

展示图片时,如果内存缓存有bitmap,则不需要从本地或者网络加载图片

代码: /** * 内存缓存 */ public class MemoryCacheUtils { private Map<String, Bitmap> mHashMap = new HashMap<>(); //写缓存 public void setMemoryCache(String url, Bitmap bitmap) { mHashMap.put(url, bitmap); } //读缓存 public Bitmap getMemroyCache(String url) { return mHashMap.get(url); } }

四个引用

强引用,StrongReference,默认,垃圾回收器不回收软引用,SoftReference,内存不足时,垃圾回收器考虑回收弱引用,WeakReference,内存不足时,垃圾回收器更会考虑回收虚引用,PhantomReference,内存不足时,垃圾回收器最会考虑回收

思路: 1. 把bitmap用SoftReference包装起来,然后再存放到map集合中 2. 读取时先获取SoftReference对象,再从软引用对象中获取bitmap

获取虚拟机分配的最大内存,默认16M long maxMemory = Runtime.getRuntime().maxMemory(); maxSize,内存缓存上限 mLruCache = new LruCache<String, Bitmap>((int) (maxMemory/8)){ //返回单个对象占用内存的大小 @Override protected int sizeOf(String key, Bitmap value) { int byteCount = value.getRowBytes() * value.getHeight(); return byteCount; } };
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表