2016-04-27 3 views
0

Я искал часы на предмет утечек памяти, и я не могу решить свою проблему. После ровно 9 поворотов мое приложение вылетает с ошибкой OutOfMemory. У меня есть как Bitmaps, так и Drawables с растровыми изображениями в моем приложении. Я попытался ввести код, который удаляет обратные вызовы для drawables, я попытался установить все битмапы на нуль, а также вручную вызвать сборщик мусора. У меня был весь этот код в методе onSaveInstanceState(), так как я предполагаю, что он вызывается всякий раз, когда экран меняется и до разрушения представления. Ни одно из этих решений не работало.Почему мое приложение утечки памяти на экране вращения?

Я получил некоторые результаты, когда растровые изображения повернули на нуль, однако это добавило только около 9 поворотов экрана перед другой утечкой памяти. Где моя утечка? Что я делаю не так? У меня создалось впечатление, что при повороте экрана все разрушается и воссоздается, что, очевидно, должно быть ложным.

Я не хочу публиковать свой код, потому что А. его много, а Б. его близок к завершению, и поэтому он становится секретом компании как таковой. Если есть что-то, что вы обязательно должны решить, я отправлю его. Я думаю, мне просто нужно действительно хорошее объяснение того, что происходит, когда экран повернут и как правильно обрабатывать растровые изображения и чертежи. Примечание. Эта ошибка не появляется, если я оставляю приложение, а затем возвращаюсь обратно, это происходит только при изменении размера представления при повороте экрана.

У меня есть около 7 растровых изображений и 7 рисунков, созданных при запуске и изменяемых при повороте экрана. Делать это несколько раз останавливает приложение.

Упрощенный код: Как настроить растровое изображение на чертеж. Это один из наборов к ClipDrawable, а также:

//Full Bar 
     colorbarMap = BitmapFactory.decodeResource(res, R.drawable.colorbar); 
     colorbarDraw = new BitmapDrawable(res, colorbarMap); 
     colorbarDraw.setBounds(barX, barY, barX2, barY2); 
     colorbarClip = new ClipDrawable(colorbarDraw, Gravity.BOTTOM, ClipDrawable.VERTICAL); 
     colorbarClip.setBounds(barX, barY, barX2, barY2); 
     colorbarClip.setLevel(currentLevel); 

     //Empty Bar 
     colorbaremptyMap = BitmapFactory.decodeResource(res, R.drawable.colorempty); 
     colorbaremptyDraw = new BitmapDrawable(res, colorbaremptyMap); 
     colorbaremptyDraw.setBounds(barX, barY, barX2, barY2); 

Приведенный выше код выполняется один раз в начале представления инициализации на основе этого кода:

private void init(){ 
     //System 
     if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB) { 
      setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
     } 
     res = getResources(); 
     options = new BitmapFactory.Options(); 

     viewTreeObserver = getViewTreeObserver(); 
     if (viewTreeObserver.isAlive()) { 
      viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
       @Override 
       public void onGlobalLayout() { 
        getViewTreeObserver().removeOnGlobalLayoutListener(this); 
        view_width = getWidth(); 
        view_height = getHeight(); 
        afterLayout(); 
       } 
      }); 
     } 
} 

Первый фрагмент кода работает по методу: afterLayout()

После этого ничего не делается с растровыми изображениями. Каждое растровое изображение инициализируется местоположением x и y на основе ширины и высоты представления. Это местоположение редактируется с использованием прямоугольника, чтобы установить его границы, например, движущегося объекта.

+0

, пожалуйста, вы можете показать свой код? Я имею в виду упрощенную версию того, что вы делаете. BitMap нужно обрабатывать с осторожностью, и без дальнейших подробностей вам будет сложно помочь – Jonsmoke

+0

вам нужно растровое изображение с высоким разрешением или растровое изображение, которое вы показываете, достаточно мало –

+1

Попробуйте использовать инструменты для разработки, такие как [LeakCanary] (https: //github.com/square/leakcanary), чтобы изолировать источник вашей трудности. Мы не можем помочь вам с совершенно абстрактным вопросом, подобным этому, особенно без [mcve]. – CommonsWare

ответ

0

Если Bitmap, который будет отображаться достаточно мал, чем использовать это или не нужно высокое разрешение изображения

bitmapOption = new BitmapFactory.Options(); 
     bitmapOption.inScaled = true; 
     bitmapOption.inSampleSize = 2; 
    imageBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(), bitmapOption); 

это уменьшит количество размера растрового изображения см лысых парней объяснение

optimizing bitmap

поместить код растровых загрузок в попытке окончательно блокировать и использовать это в конце

try { 
     ... 
}finally { 
     if (imageBitmap != null) { 
       //recycle the bitmap to improve performance and avoid OO Exception 
       imageBitmap.recycle(); 
       imageBitmap = null; 
     } 
    } 

Это будет перерабатывать пространство растрового изображения, сделанное с помощью изображения, когда GC называется

+0

Что бы я ввел в раздел try и почему я помещаю код в этот конкретный блок? Это будет работать при паузе или onResume или при инициализации? Кроме того, это не решает мою проблему, она просто отталкивает ее назад. Моя проблема возникает, когда изображения изменяются в тоннах и тоннах раз, а затем приложение падает, что-то значит почему-то, что-то не отпускается. –

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