как решить OutOfMemoryError в Android? - PullRequest
4 голосов
/ 06 марта 2012

Я подготовил № рисованной анимации. При запуске приложения будет запущена первая анимация. У меня есть две кнопки (следующая и предыдущая) с той же активностью. Когда я нажимаю на следующую кнопку, я получаю исключение, например,

 java.lang.OutOfMemoryError: bitmap size exceeds VM budget

Мой код,

Для получения рисованной анимации из рисованной

private void getAnimationForLetters(int mAnim) {
        // TODO Auto-generated method stub
        String anim = "capital_anim_" + new Integer(mAnim).toString();

        final int resID = getApplicationContext().getResources().getIdentifier(
                anim, "drawable", "my-package-name");
        mImgLetter.clearAnimation();
        mImgLetter.setBackgroundResource(resID);
        mImgLetter.post(new Runnable() {

            public void run() {
                loadingAnimation = (AnimationDrawable) mImgLetter
                        .getBackground();
                loadingAnimation.start();
            }
        });

    }

мой следующий код кнопки,

case R.id.btnNext_:
 unbindDrawables(findViewById(R.id.imgLetter));
mLetterNum=mLetterNum+1;
getAnimationForLetters(mLetterNum);

мой недопустимый нарисованный код метода,

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++) {
                unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
            ((ViewGroup) view).removeAllViews();
        }
    }

наконец я получил исключение java.lang.OutOfMemoryError: bitmap size exceeds VM budget Здесь показывается исключение mImgLetter.setBackgroundResource(resID); Пожалуйста, помогите мне.

Я добавил следующий код для очистки,

loadingAnimation.stop();
        for (int i = 0; i < loadingAnimation.getNumberOfFrames(); ++i){
            Drawable frame = loadingAnimation.getFrame(i);
            if (frame instanceof BitmapDrawable) {
                ((BitmapDrawable)frame).getBitmap().recycle();
            }
            frame.setCallback(null);
        }
        loadingAnimation.setCallback(null);

Работает нормально только для следующего или предыдущего. При первом щелчке мышью на следующей анимации переходите ко второй анимации, во второй раз, если я нажимаю на предыдущую кнопку, появляется исключение, например,

Canvas: trying to use a recycled bitmap android.graphics.Bitmap

пожалуйста, помогите мне.

Ответы [ 4 ]

3 голосов
/ 06 марта 2012
Точно

- система знает, когда нужно собирать мусор, поэтому вызов, который не поможет ни в малейшей степени.

Вы должны действительно реально управлять памятью своих приложений. 290x330 может показаться не таким уж большим, но если вы используете полный RGBA, это 4 байта на пиксель, и ваше изображение превращается в 380K. Если у вас есть несколько из них, вам не хватит памяти. Большинство устройств Android не похожи на ПК - у них довольно ограниченная память. У некоторых есть только 16M или 24M для запуска всего, включая ОС и любые другие приложения, которые пользователь может запускать одновременно.

Вы можете попробовать обернуть свою процедуру для загрузки ресурсов с помощью try / catch

 While( ! success ) {
   try {
       // load resources
  }  catch (OutOfMemoryError E) { 
       // do something to use less memory and try again
  }
 }
2 голосов
/ 06 марта 2012

Это может произойти, если вы используете изображения с высоким разрешением для мобильных телефонов с меньшим разрешением и памятью.Используйте папки Drawable-hdpi, Drawable-mdpi, Drawable-ldpi и размещайте изображения с подходящим разрешением.

FYI .. в основном вы также можете увидеть эту ошибку в эмуляторе, когда heapSize слишком мало.Попробуйте увеличить размер кучи с помощью AVD manager

. Эта ссылка может помочь вам Поддержка нескольких разрешений экрана

0 голосов
/ 06 марта 2012

Посмотрите на приведенную ниже ссылку, нехватка памяти обсуждалась подробно.

Android Недостаточно памяти

Для меня решение Томаса работало в прошлом.

Надеюсь, это поможет.

0 голосов
/ 06 марта 2012

Вы можете использовать это, чтобы освободить память:

system.gc();
...