我大约一周前在Android市场上上传了一个新的动态壁纸,并且收到了相当多的java.lang.OutOfMemoryError报告。这个错误发生在那些内存不够的小型手机上,因为无法加载我的1115 x 1000像素的图像作为动态壁纸的背景。我尝试使用inSampleSize进行缩放,但缩放后再将其恢复到正常大小时会出现模糊。请问是否有人可以为我的jpg图像提供解决此问题的示例?
我认为首先要解决的是Slayton的回复,但你也可以通过使用inPreferredConfig以及低于ARGB_8888的任何配置来节省很多内存。尝试使用RGB_565:
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inPreferredConfig = Bitmap.Config.RGB_565;
InputStream input = getAssets().open("assets/your-image.jpg");
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bounds);
在过去的几周中,我遇到了同样困难的问题。我可以成功地将1900 x 1200位图加载到我的壁纸中,但更改图像会引发内存不足错误。这是因为当您的壁纸运行时,它会创建一个壁纸引擎,如果您转到其设置,则在许多Android设备上将创建第二个预览引擎,因此您的应用程序将占用两倍的内存!
这与加载新图像时垃圾收集器(GC)缓慢有关,将创建内存不足错误。
我找到的解决方案是,在启动第二个预览时停止并卸载第一个引擎中的所有图像,使用:
bitmap.recyle();
bitmap = null;
System.gc();
try {
synchronized (this){
wait(200);
}
} catch (InterruptedException e) {
}
您需要创建一个布尔偏好来通知第一个引擎先停止动画,以便引擎1在onSharedPreferenceChanged中检测到它并停止其doDraw循环,然后清理其图像。在引擎类的onCreate中,您可以检测是否为预览模式:
boolean isPreview = this.isPreview();
我不确定wait(200)是否真的有帮助,但理论上它应该给系统更多时间来执行GC...无论如何,我成功地摆脱了OutOfMemoryError,即使是对于非常容易出现此类错误的Sony xPeria。
此外,您必须避免在动画循环中创建位图,这是绝对不行的。相反,在引擎创建时创建并重复使用切片位图。