如何避免图片加载OOM
来源:互联网 发布:罗辑思维人工智能文章 编辑:程序博客网 时间:2024/06/04 10:56
在编写程序的时候,经常需要显示很多图片,当图片质量较高,尺寸和分辨率较大时,我们的程序可能吃不消!因为程序都有一定的内存大小限制,这就可能会造成OOM(内存溢出)。
那么,该如何解决这个问题呢?思路就是,在展示高分辨率的图片的时候,肯定会对其进行压缩,然后根据控件的大小调整。
最基本的压缩方法:BitmapFactory
BitmapFactory提供了一个Options的方法,该方法里面包含了解析图片的相关参数,当我们第一次解析图片的时候因为不确定图片的大小,所以建议设置Options.InjustdecodeBounds=true,这样的话BitmapFactory.decodeResources(res,id,options)只会去解析图片的宽高和MiME类型,并不会为其分配内存,其中options.outwidth和option.height可以的到图片的宽高,知道宽高以后我们就可以对其进行缩放了,options.simpleSize这个属性可以按比例压缩图片,当然这个simpleSize需要经过计算,最后设置injustdecodebounds=false,就可以返回bitmap了
/** * @param res getResources * @param resID R.id.image * @param w 期望的宽 * @param h 期望的高 */ public static Bitmap decodeImage(Resources res, int resID, int w, int h) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; //第一次解析图片,不分配内存,只得到宽和高 BitmapFactory.decodeResource(res, resID, options); options.inSampleSize = calaculateSampleSize(options, w, h); options.inJustDecodeBounds=false; //根据得到的宽高再次解析图片 return BitmapFactory.decodeResource(res,resID,options); } static int calaculateSampleSize(BitmapFactory.Options options, int w, int h) { //图片原本的宽和高 int width = options.outWidth; int height = options.outHeight; int simpleSize = 1; if (width > w || height > h) { int widthRadio = Math.round((float) width / (float) w); int heightRadio = Math.round((float) height / (float) h); // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高 // 一定都会大于等于目标的宽和高。 simpleSize=widthRadio>heightRadio?heightRadio:widthRadio; } return simpleSize; }
OK,这只是加载一张图片,那么问题来了,如果成百上千张图片怎么办呢?程序中我们经常使用listview,girdview,recycleView等联网加载大量图片,在不断滑动的时候会不断的去解析加载图片,结果可想而知,图片不断增加,最终导致OOM,有人会说,我把屏幕之外的图片进行释放,只显示屏幕当中的图片不就行了?听起来好像没错,的确可以减轻程序的内存压力,但是另外一个问题又出现了,我们不断的回收图片,那么重新加载的时候岂不是又消耗了内存、流量和时间?这里不得不提出一个新的概念:缓存
在androidV4包中提供了一个类:LruCache,这个类提供了一套算法,可以把最近使用的对象强引用存储在LinkedHashMap ,把最近最少使用的对象在缓存达到峰值时从内存中删除,那么如何使用呢?
private LruCache<String, Bitmap> mMemoryCache;@Overrideprotected void onCreate(Bundle savedInstanceState) {// 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。// LruCache通过构造函数传入缓存值,以KB为单位。int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);// 使用最大可用内存值的1/8作为缓存的大小。int cacheSize = maxMemory / 8;mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {@Overrideprotected int sizeOf(String key, Bitmap bitmap) {// 重写此方法来衡量每张图片的大小,默认返回图片数量。return bitmap.getByteCount() / 1024;}};}public void addBitmapToMemoryCache(String key, Bitmap bitmap) {if (getBitmapFromMemCache(key) == null) {mMemoryCache.put(key, bitmap);}}public Bitmap getBitmapFromMemCache(String key) {return mMemoryCache.get(key);}public void loadBitmap(int resId, ImageView imageView) {final String imageKey = String.valueOf(resId);final Bitmap bitmap = getBitmapFromMemCache(imageKey);if (bitmap != null) {imageView.setImageBitmap(bitmap);} else {imageView.setImageResource(R.drawable.image_placeholder);BitmapWorkerTask task = new BitmapWorkerTask(imageView);task.execute(resId);}}class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {// 在后台加载图片。@Overrideprotected Bitmap doInBackground(Integer... params) {final Bitmap bitmap =decodeImage(getResources(), params[0], 100, 100);
addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);return bitmap;}}以上内容参考bolg:http://blog.csdn.net/guolin_blog/article/details/9316683
- 如何避免图片加载OOM
- 图片加载,避免OOM
- 如何避免图片oom
- 高效加载图片,避免OOM
- 图片处理,如何避免大图片加载的OOM
- Android避免加载图片出现OOM
- Android加载图片,避免OOM的解决方案
- 【Android应用】加载图片避免oom
- 图片加载,避免oom篇(1)
- 图片加载避免OOM+代码示例
- 如何高效的加载大图,避免oom
- Android 大量图片加载,使用什么加载库,避免OOM
- android 加载图片轻松避免OOM(out of memory)
- android 加载图片轻松避免OOM(out of memory)
- android 加载图片轻松避免OOM(out of memory)
- Android高效加载图片,有效避免程序OOM
- Android高效加载图片,有效避免程序OOM
- Android高效加载图片,有效避免程序OOM
- 导出product 产品,启动时会出现cmd界面
- 被Python等等乱码问题折腾的死去活来,看了几篇好文章
- JAVA方法 字符串与unicode的相互转换
- 实现QT元类型和QT线程通信
- iOS TextFiled、TextView 关于键盘的收起以及处理键盘遮挡
- 如何避免图片加载OOM
- 用VLC做流媒体服务器
- With the approaching end of FIFA 15, FIFA16 is upcoming now
- 正则匹配所有
- 判断两张图片相点击图片取色值
- 什么是性能瓶颈
- synchronized的使用规则
- Ubuntu14.04+Python3.4+apache2.4+Django1.7站点发布笔记
- DotNet中的HTTP操作