android加载图片Out Of Memory的解决
来源:互联网 发布:软件系统功能分析 编辑:程序博客网 时间:2024/05/18 16:37
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">项目中要加载从网络上获取的图片资源,但是有的图片很大,可以达到1080*1920的尺寸,这么大的图片如果全部载入内存,很容易出现Out Of Memory(OOM)的问题。</span>
解决的方法是利用BitmapFactory.Options。
HttpURLConnection hp = (HttpURLConnection) imageURL.openConnection(); InputStream is = hp.getInputStream(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; //inJustDecodeBounds设置为true后,decodeStream返回为null,但是options中存储了图片的尺寸信息 BitmapFactory.decodeStream(is, null, options); calcuteInSampleSize(options, reqWidth, reqHight); options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeStream(is, null, options);
calcuteInSampleSize方法:
public static int calcuteInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {final int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if(height > reqHeight || width > reqWidth) {final int heightRadio = Math.round((float) height / (float) reqHeight);final int widthRadio = Math.round((float) width / (float) reqWidth);inSampleSize = heightRadio > widthRadio ? widthRadio : heightRadio;}return inSampleSize;}返回的inSampleSize可以理解成为一个压缩倍数,比如inSampleSize=2,图片就会以原尺寸的1/2加载入内存。
但是使用的时候会遇到问题,第二次调用decodeStream()时,返回也为 null,log中会出现:
SkImageDecoder::Factory returned null
根据网上资料:链接
在BitmapFactory.decodeStream中 // we need mark/reset to work properly if (!is.markSupported()) { is = new BufferedInputStream(is, DECODE_BUFFER_SIZE);} // so we can call reset() if a given codec gives up after reading up to // this many bytes. FIXME: need to find out from the codecs what this // value should be.is.mark(1024);//...于是看明白了,第一次取图片尺寸的时候is这个InputStream被使用过了,再真正取图片的时候又使用了这个InputStream,此时流的起始位置已经被移动过了,需要调用is.reset()来重置,然后再decodeStream(imgInputStream, null, options)就没问题了。 但是注意一个问题,is.mark(1024)是SDK中写死的,如果图片的大小超过1024字节,第一次decode取尺寸之后调用is.reset()会抛出IOException,所以建议使用BitmapFactory的其他decode方法,如果是网络读过来的流,最好在本地存成文件缓存,然后通过decodeFileDescriptor方法就没这种问题了。我还不想去修改业务逻辑,就没使用这种方法。
使用的是另一种解决方法:
HttpClient httpClient = new DefaultHttpClient(); httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); HttpGet httpGet = new HttpGet(imageURI); //注意这里用的是URI,可以用 //imageURI = new URI(imageURL.getProtocol(), imageURL.getHost(), imageURL.getPath(), imageURL.getQuery(), null);将转换一下URL HttpResponse response = (HttpResponse).httpClient.execute(httpGet); HttpEntity entity = response.getEntity(); byte [] byteIn = EntityUtils.toByteArray(entity); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; //设置为true,返回的bitmap为null BitmapFactory.decodeByteArray(byteIn, 0, byteIn.length, options); int reqHeight = Global.g_screen_height / 3; int reqWidth = reqHeight / 5 * 3; options.inJustDecodeBounds=false; bitmap = BitmapFactory.decodeByteArray(byteIn, 0, byteIn.length, options);其实就是使用了decodeByteArray的方法。
同样的,以上解决OOM的方法也可用于decodeFile()加载本地文件使用。
0 0
- android加载图片Out Of Memory的解决
- 关于 android 加载 res 图片 out of memory 问题 解决 同样适用于 sd卡图片
- Android解决GridView异步加载大量图片时出现Out Of Memory问题00M
- Android完美解决GridView异步加载图片和加载大量图片时出现Out Of Memory问题
- Android完美解决GridView异步加载图片和加载大量图片时出现Out Of Memory问题
- Android解决GridView异步加载图片和加载大量图片时出现Out Of Memory问题--recycleBitmapCaches
- android 加载图片轻松避免OOM(out of memory)
- android 加载图片轻松避免OOM(out of memory)
- android 加载图片轻松避免OOM(out of memory)
- Android加载图片导致内存溢出(Out of Memory异常
- Android 加载图片时根据哪个类获得的值,大致判断什么时候Out Of Memory
- Android有效解决加载大图片时内存溢出的问题 Out of memory
- 解决out of memory
- 解决 out of memory 的方法
- android 加载本地图片报内存溢(out of memory)解决办法一
- Android加载图片导致内存溢出(Out of Memory异常)
- Android加载图片导致内存溢出(Out of Memory异常)
- Android加载图片导致内存溢出(Out of Memory异常)
- HDOJ 1014 模拟
- 带checkbox的ListView实现(三)——CheckableImageView的实现方法
- 数值统计
- 算法导论第十五章之钢条切割问题(自底向上版本)
- 47删除联系人的操作(有个小错误!!!)
- android加载图片Out Of Memory的解决
- ReportStudio进阶教程(三十四) - 地图开发(八)区域层、点层、显示层
- UE-Alex-js-20141125
- 移动端触屏滑动,JS事件
- Thread创建
- 第16周项目2-用指针玩转字符串-(1.2)字符串连接
- UE-JS举例
- TCP长连接与短连接的区别
- c++连接sql2005