2015-08-30 2 views
0

Этот метод принимает изображения из встроенной галереи и отправляет их на экран в виде текстуры. Я также сохраняю выбранное изображение в файле, который будет отображаться каждый раз, когда пользователь входит в этот экран. Проблема в том, что, когда я загружаю, позволяет сказать, что 3 изображения в строке я получаю предупреждение памяти в консоли, затем ведущий к приложению сбой из-за ошибки памяти:Сбой памяти из-за имитации

AppLauncher failed with an exception: java.lang.RunTimeException: The app crashed: Terminated due to Memory Error

Это трудно определить точную причину этого. Но я отлаживал и записывал бит, и не кажется, что запись изображения в файл вызывает его. Это больше связано с действием удаления уже существующего изображения и последующей загрузки. Когда я позволяю пользователю удалять их изображение, весь файл удаляется, а текстура удаляется. Я также заметил, что когда пользователь загрузил некоторые изображения и вышел из экрана, он сбой с этой ошибкой памяти.

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

Прежде всего исправить опечатку public GalleryScreen(MainClass gam**e**), вторичные вы делаете, как 12 раз одно и то же, которое отнимает много памяти в зависимости от размера изображения. Представьте, что вы загружаете 12 изображений по 12 мб каждый. Конечно, это потребует большого объема памяти, особенно если вы декодируете их на переносимые. Если вы просто загрузите их так, как они есть, вы уже будете потреблять 144 МБ бара, что очень много! Декодированные они могут быть больше!

Вот несколько советов, которые должны помочь

  1. Прежде написать чистый метод, который загружает изображение и изменяет размер его на картинку, чтобы показать. Используйте конечную локальную переменную для огромного изображения, вы можете вручную вызвать GC после загрузки некоторых изображений и изменения размера. Старайтесь избегать вызова GC, но иногда это может потребоваться. Взгляните на: why-is-it-bad-practice-to-call-system-gc
  2. Очистить код написать методу. Вы проверяете, существует ли изображение , но почему вы его проверяете doulbe? Если он существует, он загружается, поэтому если его загружен , вам не нужно его проверять, так как он находится в памяти как объект . Почему вы не загружаете его прямо в TextureRegionDrawable?
  3. Кроме того, не следует использовать 12 переменных-членов одного типа. Использовать a ArrayList и написать динамический код. Иначе вам придется снова проверить весь код , если вы что-то измените на количество снимков.
  4. libgdx is не threadsafe. Неисправность в runnable может не быть хорошим выбором. Запуск в libgdx начинается до следующего кадра. Таким образом, здесь нет ничего параллельного, поэтому нет необходимости создавать поток для публикации runnable. Взгляните на настольное приложение для бэкэнд: Dektop backend Frame method
  5. Do не создавать темы на мобильном устройстве, если вам это не нужно. Вы загрузили изображения в память и по-прежнему создавали поток, чтобы поместить их в поле. Это не имеет смысла, если они загружены.
+0

Цените свой ввод! 1. Что было бы «чистым» методом? GC = сборщик мусора? Как это назвать? 2. Загрузите «файл» прямо в TRD? 3. Вот где мое отсутствие формального образования отталкивает меня. Я не очень люблю Array или записываю динамический код для этого. 4/5. Окей. Я просто взял этот метод из wiki libgdx.Он отлично подошел, так как я хотел открыть галерею в одном потоке, чтобы пользователь мог выбрать изображение, а postRunnable, когда они были сделаны, и затем записать выбранное изображение в текстуру. – Benni

+0

Чтобы поддерживать один метод, который делает все, что вы делаете с одним изображением, является простым, а не поддерживает весь код, который вы написали. 'System.gc()' не забывайте, что это плохая практика, но в некоторых случаях это необходимо. Es direkt в TRD, например, следующим образом: 'selected1 = new TextureRegionDrawable (новый TextureRegion (новая текстура (fileIOS1)));' Да libgdx использует это для отправки runnables для следующего кадра, но это не является параллельным. На Arraylist и динамических методах вам нужно работать, так как это приятно читать и поддерживать. Старайтесь избегать писать одно и то же дважды. – BennX

+0

, поэтому один метод должен просто обрабатывать одно изображение? Просто, что я обрабатываю все «помещать содержимое файла на экран» в одном месте? Если бы я понял вас правильно? – Benni

Смежные вопросы