为了账号安全,请及时绑定邮箱和手机立即绑定

Android BitmapFactory.decodeStream方法OutOfMemoryError 解决方法

标签:
Java

我的Android App在执行下面代码时出现了OutOfMemoryError异常

image = BitmapFactory.decodeStream(assetManager.open(imgFilename));

App执行到这一步就会出现OOM异常,异常信息如下:

(...) 08-05 21:22:12.443: I/dalvikvm-heap(2319): Clamp target GC heap from 25.056MB to 24.000MB 08-05 21:22:12.443: D/dalvikvm(2319): GC_FOR_MALLOC freed <1K, 50% free 2709K/5379K, external 18296K/19336K, paused 58ms 08-05 21:22:14.513: D/dalvikvm(2319): GC_EXTERNAL_ALLOC freed <1K, 50% free 2709K/5379K, external 18296K/19336K, paused 101ms 08-05 21:22:14.903: I/dalvikvm-heap(2319): Clamp target GC heap from 25.073MB to 24.000MB 08-05 21:22:14.903: D/dalvikvm(2319): GC_FOR_MALLOC freed 0K, 50% free 2709K/5379K, external 18312K/19336K, paused 53ms 08-05 21:22:22.843: D/ddm-heap(2319): Heap GC request 08-05 21:22:22.963: I/dalvikvm-heap(2319): Clamp target GC heap from 25.073MB to 24.000MB 08-05 21:22:22.963: D/dalvikvm(2319): threadid=1: still suspended after undo (sc=1 dc=1) 08-05 21:22:22.963: D/dalvikvm(2319): GC_EXPLICIT freed 1K, 50% free 2710K/5379K, external 18312K/19336K, paused 116ms

通过DDMS可以看到当时内存堆的使用情况

  • Heap Size:  5.254 MB

  • Allocated:  2.647 MB

  • Free:   2.607 MB

  • %Used:  50.38%

  • #Objects    49,028

  

只要指定到这一行就会出现OutOfMemoryError异常

08-05 21:26:04.783: D/dalvikvm(2319): GC_EXTERNAL_ALLOC freed <1K, 50% free 2710K/5379K, external 18312K/19336K, paused 57ms 08-05 21:26:05.023: E/dalvikvm-heap(2319): 2097152-byte external allocation too large for this process. 08-05 21:26:05.163: I/dalvikvm-heap(2319): Clamp target GC heap from 25.073MB to 24.000MB 08-05 21:26:05.163: E/GraphicsJNI(2319): VM won't let us allocate 2097152 bytes 08-05 21:26:05.163: D/dalvikvm(2319): GC_FOR_MALLOC freed 0K, 50% free 2710K/5379K, external 18312K/19336K, paused 30ms 08-05 21:26:05.283: D/skia(2319): --- decoder->decode returned false

在windows中可以看到图片文件的大小是小于400K的,而BitmapFactory.decodeStream()方法却要试图分配2M的内存。

出现这个异常是因为Android类库在处理图片载入时不是很智能,我们还需要做一些额外的工作。

我测试发现,Drawable.createFromStream方法要不BitmapFactory.decodeStream方法占用更多的内存。

你可以通过修改图片的颜色模式(Color schema)来减少创建图片使用的内存量

BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Config.RGB_565; Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);

这个可以参考: http://developer.android.com/reference/android/graphics/Bitmap.Config.html

你也可以通过加载一个缩放之后的图片,来减少创建图片时的内存分配量,但是需要注意图片缩放后可能会损失质量

BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);

可以参考: http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html 要动态设置图片的inSampleSize,需要先得到图片的尺寸。

BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; bitmap = BitmapFactory.decodeStream(stream, null, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; options.inJustDecodeBounds = false; // recreate the stream // make some calculation to define inSampleSize options.inSampleSize = ?; Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);

你可以根据用户手机屏幕的大小来计算图片的尺寸,如下代码可以获得手机设备的尺寸。

DisplayMetrics metrics = new DisplayMetrics(); ((Activity) activity).getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenWidth = metrics.widthPixels; int screenHeight =metrics.heightPixels;

原文链接:http://outofmemory.cn/java/OutOfMemoryError/Android-BitmapFactory.decodeStream-method-OutOfMemoryError-solution

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消