it-roy-ru.com

Android: Java.lang.OutOfMemoryError:

Я разработал приложение, которое использует много изображений на Android.

В папке для рисования есть много изображений, скажем, более 100, я занимаюсь разработкой приложения для анимации изображений. Я использовал imageview, чтобы показать изображения GIF. Я использовал концепцию разделения изображений GIF на несколько изображений в формате PNG, а затем использовал ее. 

Каждый раз, когда пользователь входит в приложение, я вижу, как увеличивается и увеличивается объем памяти, пока пользователь не получит Java.lang.OutOfMemoryError.

Так какой же самый лучший/правильный способ обработки множества изображений?

Ниже мой код:

dog_animation.xml

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/DogView"
Android:orientation="vertical" >

<ImageView
    Android:id="@+id/dog_animation"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_weight="0.19" />

dog_animation.xml (Drawable папка)

<?xml version="1.0" encoding="utf-8"?>

<item
    Android:drawable="@drawable/image"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image1"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image2"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image3"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image4"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image5"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image6"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image7"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image8"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image9"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image10"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image11"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image12"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image13"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image14"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image15"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image16"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image17"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image18"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image19"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image20"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image21"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image22"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image23"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image24"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image25"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image26"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image27"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image28"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image29"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image30"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image31"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image32"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image33"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image34"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image35"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image36"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image37"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image38"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image39"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image40"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image41"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image42"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image43"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image44"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image45"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image46"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image47"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image48"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image49"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image50"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image51"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image52"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image53"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image54"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image55"
    Android:duration="50"/>
<item
    Android:drawable="@drawable/image56"
    Android:duration="50"/>

Dog_Animation.Java

public class Dog_Animation extends Activity {

Timer timer = new Timer();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.dog_animation);

    ImageView img = (ImageView) findViewById(R.id.dog_animation);
    img.setBackgroundResource(R.drawable.dog_animation);
    AnimationDrawable frameAnimation = (AnimationDrawable) img
            .getBackground();
    frameAnimation.start();

    timer.schedule(new TimerTask() {
        public void run() {
            Intent intent = new Intent(Dog_Animation.this,
                    Man_Animation.class);
            startActivity(intent);
        }
    }, 10000);
}
}

Теперь проблема в том, что когда я пытаюсь перейти от одного действия к другому, у которого есть то же самое другое изображение, чтобы оживить, это дает мне ошибку Java.lang.OutOfMemory.

Я пробовал так много разных решений, как

@Override
protected void onDestroy() {
    super.onDestroy();

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

и так же другие, но любое решение не работает для меня. Пожалуйста, помогите мне решить эту проблему. даже я сослался на http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/ но не смог решить проблему.

12
InnocentKiller

В вашем AndroidManifest.xml сохраните этот тег внутри приложения, добавьте largeHeap следующим образом:

<application
Android:allowBackup="true"
Android:icon="@mipmap/ic_launcher"
Android:label="@string/app_name"
Android:largeHeap="true"/>
18
Ismaran Duwadi

попробуйте остановить анимацию в onPause (). есть большой шанс, что из-за этого он не получит GCED. Также оптимизируйте ваши растровые изображения с помощью этого сайта http://tinypng.org , если вам не нужен альфа-слой, установите его на 24bit

2
hepizoj

В приведенном выше ответе отсутствует getResources() в

img.setImageBitmap(decodeSampleBitmapFromResource(R.drawable.dog_animation, width, height));

так становится

img.setImageBitmap(decodeSampleBitmapFromResource(getResources(), R.drawable.dog_animation, width, height));
1
Petar Karan

Заменить:

img.setBackgroundResource(R.drawable.dog_animation);

От:

img.setImageBitmap(decodeSampleBitmapFromResource(R.drawable.dog_animation, width, height));
//dont forget to replace width and heigh by your imageview dimension

Добавить:

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {

    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    return inSampleSize;
}

а также

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

Это из: http://developer.Android.com/training/displaying-bitmaps/load-bitmap.html

1
Pumpkin