自己写的一个图片三级缓存的工具类,下载图片使用的是volley和httpUrlConnection相同

来源:互联网 发布:2015最新dj网络歌曲 编辑:程序博客网 时间:2024/04/27 14:23


根据url加载图片时,会先从内存中找,内存缓存使用LruCache(近期最少使用算法)设置缓存图片的控件不足时,会删除最不常用的Bitmap对象。如果内存中没有,从SD卡加载。SD卡加载为防止OOM已设置虚加载。,SD卡没有从网络上下载图片,并缓存到本地和内存中。根据maxHeight和maxWidth下载需要的尺寸,虚加载的压缩比列也是根据这两个值计算,如果都传入0.代表加载原图。并且针对图片进行了优化,加载的是RGB_565格式,大小比ARGB_8888格式小了一半,但是质量差不多。不影响观看。




/**

 * 图片加载器 * Created by Ancx */ public class ImageLoader {   private static Handler handler = new Handler(); /** * 线程池 */ private final static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());   /** * 显示图片,设置默认的defaultResource、errorResource和加载原图 * * @param imgUrl 图片的Url路径 * @param imageView 显示图片的容器 */ public static void display(String imgUrl, ImageView imageView) { display(imgUrl, imageView, R.mipmap.ic_launcher,R.mipmap.ic_launcher,0,0); }   /** * 显示图片,根据type的值的不同,调用不同的显示方法 * * @param imgUrl 图片的Url路径 * @param imageView 显示图片的容器 * @param value1 type = 1时,代表 defaultResource;type = 2时,代表 maxWidth * @param value2 type = 1时,代表 errorResource;type = 2时,代表 maxHeight * @param type 等于 1 时,value为资源图片;等于 2 时,value为显示图片的最大宽和高 */ public static void display(String imgUrl, ImageView imageView, int value1, int value2, int type) { if (type == 1) { // value1为defaultResource;value2为errorResource display(imgUrl, imageView, value1, value2, 0, 0); } else if (type == 2) { // value1为maxWidth;value2为maxHeight display(imgUrl, imageView, R.mipmap.ic_launcher,R.mipmap.ic_launcher, value1, value2); } }   /** * 根据设置的属性显示图片 * * @param imgUrl 图片的Url路径 * @param imageView 显示图片的容器 * @param defaultResource 加载图片时的默认图片 * @param errorResource 加载图片失败时,显示的失败图片 * @param maxWidth 显示图片的最大宽度 * @param maxHeight 显示图片的最大高度 */ public static void display(final String imgUrl, final ImageView imageView, int defaultResource, finalinterrorResource, finalint maxWidth, final int maxHeight) { if (MemoryUtil.getBitmap(imgUrl)!=null) { // 内存中有图片,显示并结束 imageView.setImageBitmap(MemoryUtil.getBitmap(imgUrl)); return; } // 内存中没有图片,在存储卡中查找,由于可能是个耗时操作,需要先加载默认图片 imageView.setTag(imgUrl); imageView.setImageResource(defaultResource); // 开启线程在存储卡中查找图片 executorService.execute(newRunnable() { @Override public void run() { String localPath = MemoryUtil.getLocalPath(imgUrl); // 从存储卡中获取图片 final Bitmap bitmap = BitmapUtil.getStorageCardBitmap(localPath, maxWidth, maxHeight); if (bitmap != null) { // 在存储卡中找到图片 if (imgUrl.equals(imageView.getTag())) { // 如果还需要显示,那么在主线程加载图片,并缓存在内存中 handler.post(newRunnable() { @Override public void run() { // 显示图片 imageView.setImageBitmap(bitmap); } }); } // 缓存图片 MemoryUtil.putBitmap(imgUrl, bitmap); } else// 没有从存储卡中找到,从网络上下载 if (imgUrl.equals(imageView.getTag())) { downloadBitmap(imgUrl, imageView, errorResource, maxWidth, maxHeight); } } } }); }   /** * 从网络上下载图片 * * @param imgUrl 图片的Url路径 * @param imageView 显示图片的容器 * @param errorResource 加载图片失败时显示的错误图片 * @param maxWidth 显示图片的最大宽度 * @param maxHeight 显示图片的最大高度 */ private static void downloadBitmap(finalStringimgUrl, final ImageView imageView,final int errorResource,intmaxWidth, int maxHeight) { ImageRequest imageRequest = new ImageRequest(imgUrl, newResponse.Listener<Bitmap>() { @Override public void onResponse(finalBitmapbitmap) { // 从网络中获取到图片,判断是否要显示,进行显示操作 if (imgUrl.equals(imageView.getTag())) { imageView.setImageBitmap(bitmap); } // 网路上获取的图片缓存到内存中 MemoryUtil.putBitmap(imgUrl, bitmap); // 开启分线程存储图片到存储卡中 executorService.execute(newRunnable() { @Override public void run() { // 存储图片到指定目录 String localPath = MemoryUtil.getLocalPath(imgUrl); if (localPath != nullBitmapUtil.saveBitmapToFile(bitmap, localPath); } }); } }, maxWidth, maxHeight, Bitmap.Config.RGB_565,newResponse.ErrorListener() { @Override public void onErrorResponse(VolleyErrorvolleyError) { // 加载网络图片失败,显示错误图片 imageView.setImageResource(errorResource); } }); App.getQueue().add(imageRequest); } 

}



/** * 图片操作工具类 * Created by Ancx */ public class BitmapUtil {   /** * 根据路径获取存储卡中的图片对象,设置虚加载,防止内存的浪费(maxWidth || maxHeight == 0时,加载原图) * * @param localPath 图片在存储卡中的路径 * @param maxWidth 返回图片的最大宽度,为0时代表原图,与maxHeight是或的关系 * @param maxHeight 返回图片的最大高度,为0时代表原图,与maxWidth是或的关系 * @return 目标图片对象 */ public static Bitmap getStorageCardBitmap(String localPath, int maxWidth, int maxHeight) { BitmapFactory.Options options=new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.RGB_565; options.inPurgeable = true; options.inInputShareable = trueif (maxWidth != 0 && maxHeight != 0) { options.inJustDecodeBounds=trueBitmapFactory.decodeFile(localPath, options); int height = options.outHeight; int width = options.outWidth; if (height > maxHeight || width> maxWidth) { int heightRatio = Math.round((float) height/ (float) maxHeight); int widthRatio = Math.round((float) width/ (float) maxWidth); options.inSampleSize = heightRatio < widthRatio? heightRatio: widthRatio; } options.inJustDecodeBounds=false; } Bitmap bitmap = BitmapFactory.decodeFile(localPath, options); return bitmap; }   /** * 把资源文件转换成Bitmap对象 * * @param resourceId 资源文件ID * @return 转换的Bitmap对象 */ public static Bitmap getRawResourceBitmap(intresourceId) { BitmapFactory.Options opt=new BitmapFactory.Options(); opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inPurgeable = true; opt.inInputShareable = trueInputStream is = App.getInstance().getResources().openRawResource(resourceId); Bitmap bitmap = BitmapFactory.decodeStream(is,null, opt); try { is.close(); } catch (IOException e) { e.printStackTrace(); } return bitmap; }   /** * 保存Bitmap对象到存储卡 * * @param bitmap 图片对象 * @param localPath 存储的本地路径 * @return true 保存成功,false 保存失败 */ public static boolean saveBitmapToFile(Bitmap bitmap, String localPath) { boolean isCreateSuccess = FileUtil.createFile(localPath); if (!isCreateSuccess) { return false; } boolean hasSave = falseBufferedOutputStream os = nulltry { os = new BufferedOutputStream(newFileOutputStream(localPath)); bitmap.compress(Bitmap.CompressFormat.JPEG,100, os); hasSave = true; } catch (FileNotFoundException e) { hasSave = false; } finallyif (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } System.gc(); } return hasSave; } }






0 0
原创粉丝点击