Android之图片缓存
来源:互联网 发布:周杰伦侯佩岑 知乎 编辑:程序博客网 时间:2024/06/06 02:08
为了避免出现OOM,在对图片进行相关处理时,常常采用图片缓存技术。图片缓存机制常用的有两种:
- 软引用
内存缓存技术
在对图片进行加载显示之前,由于本来的图片太大,太占用内存空间,所以需要先进行图片压缩。以下是压缩图片的示例代码:
/*** 加载内存卡图片*/ BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 设置了此属性一定要记得将值设置为false Bitmap bitmap = null; bitmap = BitmapFactory.decodeFile(url, options); int be = (int) ((options.outHeight > options.outWidth ? options.outHeight / 150 : options.outWidth / 200)); if (be <= 0) // 判断200是否超过原始图片高度 be = 1; // 如果超过,则不进行缩放 options.inSampleSize = be; options.inPreferredConfig = Bitmap.Config.ARGB_4444; options.inPurgeable = true; options.inInputShareable = true; options.inJustDecodeBounds = false; try { bitmap = BitmapFactory.decodeFile(url, options); } catch (OutOfMemoryError e) { System.gc(); Log.e(TAG, "OutOfMemoryError"); }
之后再进行缓存操作,下面是两种不同的方法:
软引用
只要有足够的内存,就一直保持对象,直到发现内存吃紧且没有Strong Ref时才回收对象。我们可以这样定义:map里面的键是用来放图片地址的,既可以是网络上的图片地址,也可以SDcard上的图片地址,map里面的值里面放的是持有软引用的Bitmap,当然如果你要放Drawable,那也是可以的。
private Map<String,SoftReference<Bitmap>> imageMap = new HashMap<String,SoftReference<Bitmap>>();private Bitmap loadBitmap(final String imageUrl,final ImageCallback imageCallback){ SoftReference<Bitmap> reference = imageMap.get(imageUrl); if(reference != null){ Bitmap bitmap = reference.get(); if(bitmap != null) return bitmap; } final Handler handler = new Handler(){ public void handleMessage(final Message msg){ Bitmap bitmap = msg.obj; imageMap.put(imageUrl,new SoftReference<Bitmap>(bitmap)); if(imageCallback != null){ imageCallback.getBitmap(bitmap); } } }; new Thread(){ Message msg = handler.obtainMessage(); //网络请求,耗时操作 msg.obj = downloadBitmap(imageUrl); handler.sendMessage(msg); }.start(); return null;}privte Bitmap downloadBitmap(String imageUrl){ Bitmap bitmap = null; try{ bitmap = BitmapFactory.decodeStream(new URL(imageUrl).openStream()); return bitmap; }catch{ e.printStackTrace(); return null; }}public interface ImageCallback{ void getBitmap(Bitmap bitmap);}
内存缓存技术(LruCache技术)
在Android中,有一个叫做LruCache类专门用来做图片缓存处理的。它有一个特点,当缓存的图片达到了预先设定的值的时候,那么近期使用次数最少的图片就会被回收掉。步骤如下:
- 要先设置缓存图片的内存大小,我这里设置为手机内存的1/8,手机内存的获取方式:int MAXMEMONRY = (int)
(Runtime.getRuntime() .maxMemory() / 1024); - LruCache里面的键值对分别是URL和对应的图片。
- 重写了一个叫做sizeOf的方法,返回的是图片数量。
private LruCache<String, Bitmap> mMemoryCache;private LruCacheUtils() { if (mMemoryCache == null) mMemoryCache = new LruCache<String, Bitmap>( MAXMEMONRY / 8) { @Override protected int sizeOf(String key, Bitmap bitmap) { // 重写此方法来衡量每张图片的大小,默认返回图片数量。 return bitmap.getRowBytes() * bitmap.getHeight() / 1024; } @Override protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) { Log.v("tag", "hard cache is full , push to soft cache"); } }; }
下面的方法分别是清空缓存、添加图片到缓存、从缓存中取得图片、从缓存中移除。 移除和清除缓存是必须要做的事,因为图片缓存处理不当就会报内存溢出,所以一定要引起注意。
public void clearCache() { if (mMemoryCache != null) { if (mMemoryCache.size() > 0) { Log.d("CacheUtils", "mMemoryCache.size() " + mMemoryCache.size()); mMemoryCache.evictAll(); Log.d("CacheUtils", "mMemoryCache.size()" + mMemoryCache.size()); } mMemoryCache = null; } } public synchronized void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (mMemoryCache.get(key) == null) { if (key != null && bitmap != null) mMemoryCache.put(key, bitmap); } else Log.w(TAG, "the res is aready exits"); } public synchronized Bitmap getBitmapFromMemCache(String key) { Bitmap bm = mMemoryCache.get(key); if (key != null) { return bm; } return null; } /** * 移除缓存 * * @param key */ public synchronized void removeImageCache(String key) { if (key != null) { if (mMemoryCache != null) { Bitmap bm = mMemoryCache.remove(key); if (bm != null) bm.recycle(); } } }
引用自这篇博客
0 0
- Android之图片缓存
- Android之图片缓存
- android图片缓存之softReference
- android 图片缓存之 createBitmap
- Android之图片缓存管理
- Android之缓存网络图片
- Android之图片缓存数据流
- android图片缓存之文件(Sdcard)
- Android 之图片本地缓存解决方案
- android 之图片异步加载,带缓存。
- android代码解析之图片缓存(ImageDownloader)
- Android图片缓存之Bitmap详解
- 初识Glide-Android图片缓存之
- Android图片缓存之初识Glide
- Android图片缓存之初识Glide
- Android图片缓存之初识Glide
- Android图片缓存之初识Glide
- Android图片缓存之初识Glide
- 设计模式之观察者模式
- 字符串匹配
- Android MeasuerSpec的由来及使用
- 商业级项目登录模块源码分析
- ReactJS组件生命周期详述
- Android之图片缓存
- 【Java集合源码剖析】Vector源码剖析
- 【poj 2892】Tunnel Warfare 题意&题解&代码(C++)
- winbox常用功能
- C语言(彻底理解指针和地址,彻底!)
- mysql 打开慢查询日志
- Bootstrap 自适应窗口
- python修改操作系统时间的方法
- GPU&VS2012&CUDA&matlab&Arrayfire杂记(二)——matlab