android - OutofMemoryError - размер растрового изображения превышает бюджет виртуальной машины - при изменении ориентации

Я только начал использовать Android. Я пробовал приложения с изменением ориентации.

Я столкнулся с тем, что размер растрового изображения превышает бюджет виртуальной машины. Просмотрел много сообщений в stackoverflow и не смог понять проблему. Исключение вызывает setContentView(R.layout.level1); в onCreate. Это происходит, когда я меняю ориентацию.

Я пробовал все форумы и stackoverflow, но не мог понять. Пытаюсь исправить это последние 3 дня.

Ниже класс вызывается из другого действия при нажатии кнопки с использованием намерения и startActivity.

@Override
public void onCreate(Bundle savedInstanceState) {
    Log.d("onCreate", "onCreate");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.level1);
     if(!isOrientationChanged) //this part is executed if orientation is not changed (activity starts as usual) 
     { 
      drawableList = new ArrayList<Drawable>();
      drawableList.add( getResources().getDrawable(colorEnum[0]));
      drawableList.add( getResources().getDrawable(colorEnum[1]));
     } 
     isOrientationChanged = false;   
   timeView = (TextView) findViewById(R.id.timeView);
   colorButton = (Button) findViewById(R.id.game_button);
}


@Override
protected void onResume() {
    scoreView = (TextView) findViewById(R.id.scoreView);
    scoreView.setText("Score: " + score);
    hand.postDelayed(runThread, 0);
    super.onResume();
}


 @Override       
 public Object onRetainNonConfigurationInstance()     {          
 isOrientationChanged = true;  
 return null; //as you are not returning an object you are not leaking memory here      
 } 

@Override
protected void onPause() {
    hand.removeCallbacks(runThread);
    super.onPause();
}

 @Override
    protected void onDestroy() {
      super.onDestroy();
        unbindDrawables(findViewById(R.id.RootView));
        System.gc();
    }

    private void unbindDrawables(View view) {
        if (view.getBackground() != null) {
            view.getBackground().setCallback(null);
        }
       if (view instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
                Log.d("onDestroy","Inside loop to getting child "+((ViewGroup) view).getChildAt(i));
                unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
            ((ViewGroup) view).removeAllViews();
        }
       hand.removeCallbacks( runThread); 
    }

/** The run thread. */
Thread runThread = new Thread() {
    @Override
    public void run() {
        timeView.setText("Time Left: " + timeLeftVal);
                :
                :
                :
        } else {
        changeColor();
        :
        :
            hand.postDelayed(runThread, GET_DATA_INTERVAL);
        }
    }
};
/**
 * Change color.
 */
private void changeColor() {
    colorButton.setBackgroundDrawable(drawableList.get(randomNum));

}

  1. В методе onCreate создание рисуемого списка и его инициализация при первой загрузке.
  2. Использование Thread для случайной установки фона изображения кнопки
  3. Вызов метода unbindDrawables() onDestroy, чтобы при изменении ориентации старый вид удалялся из памяти.
  4. hand.removeCallbacks(runThread) также вызывается в методе onPause
  5. вернул null в onRetainNonConfigurationInstance()

Я исправил проблему. Маленькая ошибка привела к этой большой проблеме. Я использовал Thread вместо Runnable в Handler. Следовательно, removeCallback не работал должным образом.


person sharmi    schedule 09.12.2011    source источник
comment
Какова ваша настройка файла манифеста? , вы передаете изменения ориентации активности для обработки вручную или вы идете по старинке и часто терпите крах, уничтожая и перестраивая?   -  person Chris    schedule 09.12.2011
comment
Каков размер изображений, которые вы загружаете? Сколько изображений вы загружаете? Как сказал Крис, при смене ориентации вся деятельность разрушается и перезагружается. Проблема, вероятно, в том, что изображения предыдущей ориентации все еще загружаются, а изображения следующей ориентации загружаются. Приложение вылетает из-за нехватки памяти в WM. Вызов unbindDrawables() System.gc() не гарантирует, что изображения будут выгружены перед загрузкой следующих изображений.   -  person jobesu    schedule 09.12.2011
comment
Хорошая статья об этом: android-developers.blogspot.com /2009/02/   -  person MobileCushion    schedule 09.12.2011
comment
Я не обрабатываю изменения ориентации вручную. Как заявил Джобесу, проблема может заключаться в том, что unbindDrawables() и System.gc() не выгрузили предыдущие изображения. Пользовательский интерфейс имеет одну кнопку, цвет фона которой меняется случайным образом, и два текстовых представления для отображения данных. Следовательно, есть элементы, которые создаются и уничтожаются при каждом изменении ориентации. Я не знаю, как удалить старые представления об изменении ориентации.   -  person sharmi    schedule 12.12.2011


Ответы (1)


Надеюсь, что следующие ссылки помогут:

Статья об анализаторе памяти Eclipse

Видео на YouTube

Поиск в Google: "Управление памятью Google IO 2011 для приложений Android"

person Ghost    schedule 14.12.2011