【问题标题】:java.lang.OutOfMemoryError loading Images in Codename Onejava.lang.OutOfMemoryError loading Images in Codename One
【发布时间】:2019-09-18 10:46:12
【问题描述】:

这个问题只涉及代号一。

我有一个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$1.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$6.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$1.run(CodenameOneThread.java:60)
        at java.lang.Thread.run(Thread.java:776)

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

每张图片在显示之前都会被缩放(使用 FixedSizeButton 类,我在 this question 中报告过)。有什么建议吗?

我猜Imagedispose() 方法可能很有用,但它写的是“除非您知道自己在做什么,否则不要调用此方法”。有那么大问题吗?例如,如果我在将图像保存到文件和/或缩放后dispose 图像会有帮助吗?

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

但是,如果很少有照片有这么大的问题……我怎样才能在Form 内创建照片库而不会出现此类问题?在InfiniteContainer 中加载数百张照片帖子也有同样的问题...

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

感谢您的建议。

【问题讨论】:

    标签: codenameone


    【解决方案1】:

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

    所以 36 x 8 = 288mb 的 RAM。

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

    什么是图像宽度/高度?

    您可能会在这里占用大量内存...

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 2022-12-27
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多