对图片进行缓存,刚开始的做法是实现三级缓存:
内存缓存,优先加载,速度最快
本地缓存,次优先加载,速度块
网络缓存,不优先加载,速度慢,浪费流量
网络缓存是直接通过向服务器请求,获取图片
本地缓存是将从网络请求后得到的图片保存至本地sdcard中
本地缓存是将从网络请求后得到的图片保存至内存中
但是手机的内存是有限的,而且给每个应用分配的内存也是很小的,所以容易造成内存溢出(OOM);
解决此办法是使用弱引用,因为弱引用在内存不够时,垃圾回收机制会将其回收,才会保持足够的空间。
弱引用:SoftReference:
HashMap<String,SoftReference<Bitmap>>hashMap=new HashMap<>();
但是在Android2.3+,这种弱引用很容易就被回收,所以达不到原有的效果
解决办法是使用:LruCache;
将内存控制在一定大小内,超出最大值会自动回收,这个最大值开发者自己定
LruCache memoryCache=new LruCache<String, Bitmap>((int) maxSize){ @Override protected int sizeOf(String key, Bitmap value) { int byteCount=value.getRowBytes()*value.getHeight();//图片的大小 return byteCount; } };
对图片的压缩
//进行图片的压缩 BitmapFactory.Options option=new BitmapFactory.Options(); option.inSampleSize=2;//压缩至原图片的1/2 option.inPreferredConfig= Bitmap.Config.RGB_565;//设置图片的格式 Bitmap bitmap= BitmapFactory.decodeStream(is,null,option);
最后贴上代码:
网络缓存:
public class NetChache { private ImageView ivPic; private String url; private LocalCacheUtil localCache; private MemoryCacheUtil memoryCache; public NetChache(LocalCacheUtil localCache,MemoryCacheUtil memoryCache){ this.localCache=localCache; this.memoryCache=memoryCache; } /* * 从网络下载图片 * */ public Bitmap getBitmapFromNet(ImageView ivPic, String url) { new BitmapTask().execute(ivPic, url); return null; } /* * Handler与线程池的封装 * */ class BitmapTask extends AsyncTask<Object, Void, Bitmap> { /* * 后台执行耗时操作 * 子线程 * */ @Override protected Bitmap doInBackground(Object... params) { ivPic = (ImageView) params[0]; url = (String) params[1]; // ivPic.setTag(url); return downloadBitmap(url); } /* * 更新进度 * 主线程 * */ @Override protected void onProgressUpdate(Void... values) { super.onProgressUpdate(values); } /* * 耗时方法执行完毕,执行此方法 * */ @Override protected void onPostExecute(Bitmap bitmap) { if (bitmap!=null){ ivPic.setImageBitmap(bitmap); //缓存至本地 localCache.setBitmapToLocal(url,bitmap); memoryCache.setBitmapToMemory(url,bitmap); } } } private Bitmap downloadBitmap(String url) { HttpURLConnection connection=null; try { URL u = new URL(url); connection= (HttpURLConnection) u.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); if (connection.getResponseCode()==200){ InputStream is=connection.getInputStream(); //进行图片的压缩 BitmapFactory.Options option=new BitmapFactory.Options(); option.inSampleSize=2;//压缩至原图片的1/2 option.inPreferredConfig= Bitmap.Config.RGB_565;//设置图片的格式 Bitmap bitmap= BitmapFactory.decodeStream(is,null,option); return bitmap; } } catch (Exception e) { e.printStackTrace(); }finally { connection.disconnect(); } return null; } }
本地缓存:
public class LocalCacheUtil { public static final String CACHE_PATH= Environment. getExternalStorageDirectory()+ "/sendizhihui_cache"; /* * 从本地sdcard读取图片 * */ public Bitmap getBitmapFromLocal(String url){ try { String fileName=MD5Encoder.encode(url); File file=new File(CACHE_PATH,fileName); if (file.exists()){ Bitmap bitmap= BitmapFactory.decodeStream(new FileInputStream(file)); return bitmap; } } catch (Exception e) { e.printStackTrace(); } return null; } /* * 向sdcard写图片 * */ public void setBitmapToLocal(String url, Bitmap bitmap){ try { String fileName=MD5Encoder.encode(url); File file=new File(CACHE_PATH,fileName); File parentFile=file.getParentFile(); if (!parentFile.exists()) {//如果文件夹不存在,则创建文件夹 parentFile.mkdirs(); } bitmap.compress(Bitmap.CompressFormat.JPEG,100, new FileOutputStream(file)); } catch (Exception e) { e.printStackTrace(); } } }内存缓存:
public class MemoryCacheUtil { // HashMap<String,SoftReference<Bitmap>>hashMap=new HashMap<>(); private LruCache<String,Bitmap>memoryCache; public MemoryCacheUtil(){ long maxSize=Runtime.getRuntime().maxMemory()/8;//模拟器默认为16m memoryCache=new LruCache<String, Bitmap>((int) maxSize){ @Override protected int sizeOf(String key, Bitmap value) { int byteCount=value.getRowBytes()*value.getHeight();//图片的大小 return byteCount; } }; } /* * 从内存读取 * */ public Bitmap getBitmapFromMemory(String url){ // //弱引用 // SoftReference<Bitmap>softReference=hashMap.get(url); // if (softReference!=null){ // Bitmap bitmap=softReference.get(); // return bitmap; // } return memoryCache.get(url); } /* * 将图片写进内存 * */ public void setBitmapToMemory(String url,Bitmap bitmap){ // SoftReference<Bitmap>softReference=new SoftReference<Bitmap>(bitmap); // hashMap.put(url,softReference); memoryCache.put(url,bitmap); } }