图像存储导致内存崩溃

时间:2015-08-30 12:03:53

标签: ios memory libgdx

此方法从内置图库中获取图像,并以纹理的形式将它们提交到屏幕。我还将他们选择的图像存储在每次用户进入该屏幕时要呈现的文件中。问题是,当我上传时,连续说3个图像我在控制台中收到内存警告,之后导致应用程序因内存错误而崩溃:

  

AppLauncher因异常而失败:   java.lang.RunTimeException:应用程序崩溃:由于内存错误而终止

很难找到确切原因。但是我已经调试并记录了一点,并且看起来将图像写入文件并不会导致它。它与删除现有图像然后上传替换图片的操作更相关。当我让用户删除他们的图像时,整个文件被删除并且纹理被丢弃。我还注意到,当用户上传了一些图像并退出屏幕时,它会因内存错误而崩溃。

    FileHandle fileIOS1 = Gdx.files.external("iosImage1.png");
    FileHandle fileIOS2 = Gdx.files.external("iosImage2.png");
    FileHandle fileIOS3 = Gdx.files.external("iosImage3.png");
    FileHandle fileIOS4 = Gdx.files.external("iosImage4_.png");
    FileHandle fileIOS5 = Gdx.files.external("iosImage5.png");
    FileHandle fileIOS6 = Gdx.files.external("iosImage6.png");
    FileHandle fileIOS7 = Gdx.files.external("iosImage7.png");
    FileHandle fileIOS8 = Gdx.files.external("iosImage8.png");
    FileHandle fileIOS9 = Gdx.files.external("iosImage9.png");
    FileHandle fileIOS10 = Gdx.files.external("iosImage10.png");
    FileHandle fileIOS11 = Gdx.files.external("iosImage11.png");
    FileHandle fileIOS12 = Gdx.files.external("iosImage12.png");

    public GalleryScreen(MainClass game) {
    if(game.isIOS()){
        if(fileIOS1.exists()) {
            imageSelected1 = new Texture(fileIOS1);
        }
        if(fileIOS2.exists()) {
            imageSelected2 = new Texture(fileIOS2);
        }
        if(fileIOS3.exists()) {
            imageSelected3 = new Texture(fileIOS3);
        }
        if(fileIOS4.exists()) {
            imageSelected4 = new Texture(fileIOS4);
        }
        if(fileIOS5.exists()) {
            imageSelected5 = new Texture(fileIOS5);
        }
        if(fileIOS6.exists()) {
            imageSelected6 = new Texture(fileIOS6);
        }
        if(fileIOS7.exists()) {
            imageSelected7 = new Texture(fileIOS7);
        }
        if(fileIOS8.exists()) {
            imageSelected8 = new Texture(fileIOS8);
        }
        if(fileIOS9.exists()) {
            imageSelected9 = new Texture(fileIOS9);
        }
        if(fileIOS10.exists()) {
            imageSelected10 = new Texture(fileIOS10);
        }
        if(fileIOS11.exists()) {
            imageSelected11 = new Texture(fileIOS11);
        }
        if(fileIOS12.exists()) {
            imageSelected12 = new Texture(fileIOS12);
        }
    }

    @Override
    public void show() {
    if(game.isIOS()){
        if(fileIOS1.exists()) {
            selected1 = new TextureRegionDrawable(new TextureRegion(imageSelected1));
            style2.up = skin.newDrawable(skin.newDrawable(selected1));
            style2.down = skin.newDrawable(skin.newDrawable(selected1));
        }

        if(!fileIOS1.exists()){
            style2.up = skin.newDrawable(skin.newDrawable(temp));
            style2.down = skin.newDrawable(skin.newDrawable(temp));
        }
        if(fileIOS2.exists()) {
            selected2 = new TextureRegionDrawable(new TextureRegion(imageSelected2));
            style3.up = skin.newDrawable(skin.newDrawable(selected2));
            style3.down = skin.newDrawable(skin.newDrawable(selected2));
        }

        if(!fileIOS2.exists()){
            style3.up = skin.newDrawable(skin.newDrawable(temp));
            style3.down = skin.newDrawable(skin.newDrawable(temp));
        }
        if(fileIOS3.exists()){
            selected3 = new TextureRegionDrawable(new TextureRegion(imageSelected3));
            style4.up = skin.newDrawable(skin.newDrawable(selected3));
            style4.down = skin.newDrawable(skin.newDrawable(selected3));
        }
        if(!fileIOS3.exists()){
            style4.up = skin.newDrawable(skin.newDrawable(temp));
            style4.down = skin.newDrawable(skin.newDrawable(temp));
        }
    Gdx.app.log("HERE:", "6");
        if(fileIOS4.exists()){
            selected4 = new TextureRegionDrawable(new TextureRegion(imageSelected4));
            style5.up = skin.newDrawable(skin.newDrawable(selected4));
            style5.down = skin.newDrawable(skin.newDrawable(selected4));
        }
    Gdx.app.log("HERE:", "7");
        if(!fileIOS4.exists()){
            style5.up = skin.newDrawable(skin.newDrawable(temp));
            style5.down = skin.newDrawable(skin.newDrawable(temp));
        }
        if(fileIOS5.exists()){
            selected5 = new TextureRegionDrawable(new TextureRegion(imageSelected5));
            style6.up = skin.newDrawable(skin.newDrawable(selected5));
            style6.down = skin.newDrawable(skin.newDrawable(selected5));
        }
        if(!fileIOS5.exists()){
            style6.up = skin.newDrawable(skin.newDrawable(temp));
            style6.down = skin.newDrawable(skin.newDrawable(temp));
        }
        if(fileIOS6.exists()){
            selected6 = new TextureRegionDrawable(new TextureRegion(imageSelected6));
            style7.up = skin.newDrawable(skin.newDrawable(selected6));
            style7.down = skin.newDrawable(skin.newDrawable(selected6));
        }
        if(!fileIOS6.exists()){
            style7.up = skin.newDrawable(skin.newDrawable(temp));
            style7.down = skin.newDrawable(skin.newDrawable(temp));
        }

    if(fileIOS7.exists()){
        selected7 = new TextureRegionDrawable(new TextureRegion(imageSelected7));
        style8.up = skin.newDrawable(skin.newDrawable(selected7));
        style8.down = skin.newDrawable(skin.newDrawable(selected7));
    }
    if(!fileIOS7.exists()){
        style8.up = skin.newDrawable(skin.newDrawable(temp));
        style8.down = skin.newDrawable(skin.newDrawable(temp));
    }
    if(fileIOS8.exists()){
        selected8 = new TextureRegionDrawable(new TextureRegion(imageSelected8));
        style9.up = skin.newDrawable(skin.newDrawable(selected8));
        style9.down = skin.newDrawable(skin.newDrawable(selected8));
    }
    if(!fileIOS8.exists()){
        style9.up = skin.newDrawable(skin.newDrawable(temp));
        style9.down = skin.newDrawable(skin.newDrawable(temp));
    }
    if(fileIOS9.exists()){
        selected9 = new TextureRegionDrawable(new TextureRegion(imageSelected9));
        style10.up = skin.newDrawable(skin.newDrawable(selected9));
        style10.down = skin.newDrawable(skin.newDrawable(selected9));
    }
    if(!fileIOS9.exists()){
        style10.up = skin.newDrawable(skin.newDrawable(temp));
        style10.down = skin.newDrawable(skin.newDrawable(temp));
    }
    if(fileIOS10.exists()){
        selected10 = new TextureRegionDrawable(new TextureRegion(imageSelected10));
        style11.up = skin.newDrawable(skin.newDrawable(selected10));
        style11.down = skin.newDrawable(skin.newDrawable(selected10));
    }
    if(!fileIOS10.exists()){
        style11.up = skin.newDrawable(skin.newDrawable(temp));
        style11.down = skin.newDrawable(skin.newDrawable(temp));
    }
    if(fileIOS11.exists()){
        selected11 = new TextureRegionDrawable(new TextureRegion(imageSelected11));
        style12.up = skin.newDrawable(skin.newDrawable(selected11));
        style12.down = skin.newDrawable(skin.newDrawable(selected11));
    }
    if(!fileIOS11.exists()){
        style12.up = skin.newDrawable(skin.newDrawable(temp));
        style12.down = skin.newDrawable(skin.newDrawable(temp));
    }
    if(fileIOS12.exists()){
        selected12 = new TextureRegionDrawable(new TextureRegion(imageSelected12));
        style13.up = skin.newDrawable(skin.newDrawable(selected12));
        style13.down = skin.newDrawable(skin.newDrawable(selected12));
    }
    if(!fileIOS12.exists()){
        style13.up = skin.newDrawable(skin.newDrawable(temp));
        style13.down = skin.newDrawable(skin.newDrawable(temp));
    }
}boxImage1.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {

                    if(!fileIOS1.exists()) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                gallery.iosPickImage1();
                                Gdx.app.postRunnable(new Runnable() {
                                    @Override
                                    public void run() {
                                        imageSelected1 = new Texture(fileIOS1);

                                        selected1 = new TextureRegionDrawable(new TextureRegion(imageSelected1));

                                        style2.up = skin.newDrawable(skin.newDrawable(selected1));
                                        style2.down = skin.newDrawable(skin.newDrawable(selected1));
                                    }
                                });
                            }
                        }).start();
                    }
                    if(!fileIOS2.exists()) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                gallery.iosPickImage2();
                                Gdx.app.postRunnable(new Runnable() {
                                    @Override
                                    public void run() {
                                        Gdx.app.log("CREATING IMAGE" , "1");
                                        imageSelected2 = new Texture(fileIOS2);
                                        Gdx.app.log("CREATING IMAGE" , "2");
                                        selected2 = new TextureRegionDrawable(new TextureRegion(imageSelected2));
                                        Gdx.app.log("CREATING IMAGE" , "3");
                                        style3.up = skin.newDrawable(skin.newDrawable(selected2));
                                        style3.down = skin.newDrawable(skin.newDrawable(selected2));
                                    }
                                });
                            }
                        }).start();
                    }

1 个答案:

答案 0 :(得分:1)

首先修复你的拼写错误public GalleryScreen(MainClass gam**e** ),你做的次要事情是12次相同的事情,这取决于图像的大小。想象一下,你加载了每张12mb的12张图像。当然,这将需要大量的内存,特别是如果你将它们解码为drawable。如果您只是按原样加载它们,那么您已经消耗了144mb的ram,这很多!解码它们可能会更大!

以下是一些应该提供帮助的提示

  1. 首先编写一个清理方法,它会加载图像并调整大小 它以缩略图显示。对于巨大的图像使用最终的局部变量,可以在加载一些图片并调整其大小后手动调用GC。尽量避免GC调用,但有时可能需要它。请查看:why-is-it-bad-practice-to-call-system-gc
  2. 清理代码编写方法。您正在检查图像是否存在 但你为什么要检查它?如果它存在它的负载,如果它 加载你不需要再次检查它,因为它在内存中 宾语。为什么不直接将它加载到TextureRegionDrawable?
  3. 此外,不要做12个相同类型的成员变量。使用 a ArrayList和编写动态代码。否则你将需要检查整体 如果您更改了图片计数,请再次编码。
  4. libgdx 不是线程安全。在runnable中生成一个runnable可能不是一个好选择。 libgdx中的runnable在下一帧之前开始。所以没有什么是平行的,所以没有必要产生一个线程来发布一个runnable。请查看桌面后端应用:Dektop backend Frame method
  5. 如果您不需要,不会在移动设备上生成线程。你把图片加载到内存中,然后产生一个线程将它们放到盒子里。如果加载它们就没有意义。