java.lang.OutOfMemoryError 加载代号一中的图片

java.lang.OutOfMemoryError loading Images in Codename One

此问题仅针对代号一。

我有一个 Form 和一个 Tabs,每个选项卡可以包含任意数量的图像(从图库中获取)。

结果:几张图片(图库中的八张图片)后,在我的 Android 设备上我得到:

java.lang.OutOfMemoryError: Failed to allocate a 5683356 byte allocation with 1845080 free bytes and 1801KB until OOM
        at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
        at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
        at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:737)
        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:703)
        at com.codename1.impl.android.c.b(AndroidImplementation.java:2037)
        at com.codename1.r.z.a(Image.java:531)
        at cool.teammate.apps.frontend.b.e.a.a(BasePageForm.java:208)
        at com.codename1.r.l.b.a(EventDispatcher.java:349)
        at com.codename1.impl.android.c.a(AndroidImplementation.java:7336)
        at com.codename1.impl.android.CodenameOneActivity.run(CodenameOneActivity.java:527)
        at com.codename1.r.r.n(Display.java:1298)
        at com.codename1.r.r.l(Display.java:1242)
        at com.codename1.r.r.k(Display.java:1130)
        at com.codename1.r.aq.run(RunnableWrapper.java:120)
        at com.codename1.impl.b.run(CodenameOneThread.java:60)
        at java.lang.Thread.run(Thread.java:776)

也iOS崩溃,但我没有日志。

每张图片在显示前都进行了缩放(使用我在 中报告的 class FixedSizeButton)。有什么建议吗?

估计Imagedispose()方法可以用,但是写到"DO NOT CALL THIS METHOD UNLESS YOU KNOW WHAT YOU ARE DOING"。有这么麻烦吗?例如,如果我 dispose 图像在缩放后保存到文件 and/or 后会有帮助吗?

我也猜想 System.gc() 会有用。

但是,如果很少有照片有问题...我怎样才能在 Form 中制作照片库而不出现此类问题?在 InfiniteContainer...

中加载数百张照片 post 同样的问题

请注意,无论我将图像作为 Buttonicon 还是作为 Button 的填充背景插入,内存问题都会发生。

感谢您的建议。

您无需致电 dispose()gc() 即可获得适当的申请。您正在尝试加载一个 5mb 的图像,我假设它是一个 5mb 的 JPEG。这可能来自 9+ 兆像素相机,这意味着解压缩后的大小大约为 9 x 4 == 36MB!

所以 36 x 8 = 288mb 内存。

    this.image = Image.createImage(this.imageWidth, this.imageHeight, 0xFFdddddd);

什么是 imageWidth/Height?

您可能在这里占用了大量 RAM...

    this.setIcon(this.image);

    EasyThread scalingThread = EasyThread.start("FixedSizeButton-ScalingImg-" + fileName);

由于您正在创建多个线程,因此您可能会同时在 RAM 中拥有所有 8 个图像。

更好的方法是使用一个图像缩放线程。更好的方法是完全避免 scaled 并使用 ImageIO 缩放图像而不将其加载到 RAM 中。