在Galaxy Nexus上使用LiveWallpaper时遇到了Bitmap的OutOfMemory错误

3
我有一个Android应用程序,需要将大约30个大小为455x320像素的jpg文件加载到内存中。
在我测试过的所有设备上,包括G1和Galaxy Nexus,这都能正常工作。
我还有一个版本是动态壁纸,它可以在Nexus One、Milestone、Galaxy S2和一些3.x平板电脑上运行。但是,我的动态壁纸版本在Galaxy Nexus(ICS系统)上会因为内存溢出而崩溃。
以下是我使用的简化代码:
Bitmap bitmap = BitmapFactory.decodeResource(
  lwpService.getResources(), R.drawable.somepic);
imageCache.put(R.drawable.somepic, bitmap);
bitmap = BitmapFactory.decodeResource(
  lwpService.getResources(), R.drawable.someotherpic);
imageCache.put(R.drawable.someotherpic, bitmap);
… // and so on for 30 more images.

以下是来自logcat的堆栈跟踪信息:
02-12 00:07:34.456 E/dalvikvm-heap( 6938): Out of memory on a 583696-byte allocation.
02-12 00:07:34.456 I/dalvikvm( 6938): "Thread-7378" prio=5 tid=16 RUNNABLE
02-12 00:07:34.456 I/dalvikvm( 6938):   | group="main" sCount=0 dsCount=0 obj=0x4186c3f8 self=0x20e538
02-12 00:07:34.456 I/dalvikvm( 6938):   | sysTid=7115 nice=0 sched=0/0 cgrp=default handle=2213784
02-12 00:07:34.456 I/dalvikvm( 6938):   | schedstat=( 0 0 0 ) utm=6907 stm=504 core=1
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.Bitmap.nativeCreate(Native Method)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:524)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:499)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:351)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:374)
02-12 00:07:34.463 I/dalvikvm( 6938):   at com.myapp.loadImage(MyApp.java:155)

有没有其他人在Galaxy Nexus上的LWP中加载多个位图时遇到问题?

编辑: 我已经找到了一个避免OutOfMemoryErrors的方法:由于我的特定图像是不透明的,所以我不需要alpha通道,因此我可以使用Bitmap.Config.RGB_565而不是Bitmap.Config.RGB_8888。这样,我的图像使用的内存量只有之前的一半。

BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;    
Bitmap bitmap = BitmapFactory.decodeResource(
    lwpService.getResources(), R.drawable.somepic, options);

我认为这种解决方案在处理更多或更大的图片时不会很有效,所以我仍然对其他评论感兴趣。

1个回答

0

好的,你的解决方案将内存占用减少了一半(从RGB_8888的4个字节到RGB_565的2个字节)。但是这里真正的问题是为什么需要同时加载所有图像?动态壁纸的平均主屏幕尺寸为960 x 800,那么加载30个455x320的图像的原因是什么?它不适合,即使这个解决方案在大多数手机上都可以工作,你仍然使用了大量的内存。我建议你使用位图池动态加载图像并回收它们。祝好!


320x455分辨率图像的原因是这最初是G1上的一个应用程序,后来我将其改编为动态壁纸。有30张图片的原因是它们用于各种动画。我尝试过不加载和缓存它们,但动画变得相当慢。我尝试仅加载和缓存给定动画的特定图像,但仍然出现OOM错误。恐怕对于一组图像,找到最佳大小可能会很困难:太大了,我会遇到OOM错误,太小了,我的动画就会很卡顿。 - Carmen
可能有一种方法可以优化我的代码(除了我已经找到的解决方案)。但让我困惑的是,相同的逻辑在2.x和3.x上都能正常工作,但在4.x上却不能。 - Carmen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接