web-dev-qa-db-fra.com

Android: Java.lang.OutOfMemoryError:

J'ai développé une application qui utilise beaucoup d'images sur Android.

Il y a beaucoup d'images présentes dans des dossiers pouvant être dessinés, disons plus de 100, je développe une application pour l'animation d'images. J'ai utilisé imageview pour afficher des images GIF. J'ai utilisé le concept d'images Split gif en plusieurs images au format PNG, puis je l'utilise. 

Chaque fois que l'utilisateur entre dans l'application, la mémoire augmente de plus en plus jusqu'à ce que l'utilisateur obtienne le Java.lang.OutOfMemoryError.

Alors, quel est le meilleur/bon moyen de gérer de nombreuses images?

Ci-dessous mon code:

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 (dossier dessinable)

<?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);
}
}

Maintenant, le problème, c’est que lorsque j’essaie de passer d’une activité à une autre qui a même une autre image à animer, cela me donne une erreur de Java.lang.OutOfMemory.

J'ai essayé avec tellement de solutions différentes comme

@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();
    }
}

et si d'autres aussi, mais aucune solution ne fonctionne pour moi. S'il vous plaît aidez-moi à résoudre ce problème. même si j'ai référé http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/ ce lien, mais que le problème n'a pas été résolu.

12
InnocentKiller

Dans votre fichier AndroidManifest.xml, conservez cette balise à l'intérieur de l'application, ajoutez largeHeap comme ceci:

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

essayez d’arrêter votre animation à onPause (). il y a de grandes chances que cela ne soit pas obtenu à l'aide du système GCED. optimise également vos bitmaps avec ce site http://tinypng.org , si vous n’avez pas besoin de la couche alpha, réglez-le sur 24 bits.

2
hepizoj

Dans la réponse ci-dessus, il manque une getResources() dans

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

alors ça devient

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

Remplacer:

img.setBackgroundResource(R.drawable.dog_animation);

Par:

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

Un ajout:

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;
}

et

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);
}

Cela provient de: http://developer.Android.com/training/displaying-bitmaps/load-bitmap.html

1
Pumpkin