Affichage d'images jpg : java.lang.OutOfMemoryError

Résolu/Fermé
michelmouton Messages postés 7 Date d'inscription samedi 23 août 2014 Statut Membre Dernière intervention 17 mars 2015 - 16 mars 2015 à 12:09
michelmouton Messages postés 7 Date d'inscription samedi 23 août 2014 Statut Membre Dernière intervention 17 mars 2015 - 17 mars 2015 à 11:10
Bonjour !

Je suis en train de créer une application android qui affiche une image par page (par activité). En cliquant sur un bouton, on passe à une nouvelle page (nouvelle activité) et on affiche une nouvelle image.

Cependant, je rencontre de temps un problème : de temps en temps l'application se ferme et le débogueur affiche :

03-16 11:57:05.881 15713-15713/fr.maxiapp.lesaliments E/AndroidRuntime? FATAL EXCEPTION: main
Process: fr.maxiapp.lesaliments, PID: 15713
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:594)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:429)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:856)
at android.content.res.Resources.loadDrawable(Resources.java:2122)
at android.content.res.Resources.getDrawable(Resources.java:707)
at android.widget.ImageView.resolveUri(ImageView.java:638)
at android.widget.ImageView.setImageResource(ImageView.java:367)
at fr.maxiapp.lesaliments.AffichageIdeeActivity.onCreate(AffichageIdeeActivity.java:95)
at android.app.Activity.performCreate(Activity.java:5240)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2216)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2301)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5196)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)


L'affichage d'une image se fait de la façon suivante :

image_en_cours.setImageResource(img.getUneImage(numImageEnCours+1));

Avec img.getUneImage(numImageEnCours+1) renvoyant un identifiant (int) de la forme R.drawable.imageXXX.

Naturellement, j'ai cherché cette erreur sur google, et elle indique apparemment un problème de mémoire (photo trop lourde ?) mais je ne trouve pas de solution pour la corriger.
Peut-être que je libère mal la mémoire après en avoir fini avec une image ?

Auriez-vous une solution ?

Je vous remercie d'avance :)

A bientôt !
A voir également:

5 réponses

michelmouton Messages postés 7 Date d'inscription samedi 23 août 2014 Statut Membre Dernière intervention 17 mars 2015
16 mars 2015 à 13:16
Bonjour et merci pour ta réponse.

En réalité, je ne libère pas vraiment la mémoire quand j'y pense : j'avais essayé de mettre tout un tas de trucs différents dans la méthode onDestroy() mais rien ne corrigeait le problème.

La libération de la mémoire est bien censée être ordonnée dans cette méthode ?
Et quelle commande appeler ?
J'avais essayé ça :


unbindDrawables(findViewById(R.id.mainLayout));
System.gc();


Mais sans succès ...

Merci de votre aide !
0
michelmouton Messages postés 7 Date d'inscription samedi 23 août 2014 Statut Membre Dernière intervention 17 mars 2015
16 mars 2015 à 13:45
Je parle de la méthode onDestroy, commune à chaque activité Android.

J'entends bien que chaque situation est différente mais je ne vois pas quel autre bout de code t'intéresserait. Le reste ne concerne ni l'affichage d'une image ni la libération de la mémoire associée.

En réalité, ma question est très précise : comment afficher une image jpg tout en évitant cette erreur ? Qu'écrire dans la méthode onDestroy() pour libérer la mémoire d'une image ?

Si tu y tiens , je peux vous transmettre tout le code de mon activité mais je doute que cela te soit très utile ...

Merci en tout cas :)
0
BunoCS Messages postés 15475 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 23 avril 2024 3 894
16 mars 2015 à 14:11
Hello,

Effectivement, c'est un souci de mémoire. Plusieurs solutions:
- retailler tes images: inutile d'avoir des images de 2500x2500 pixels sur un téléphone
- redimensionner à la volée ton image en fonction de ta taille d'écran avec, de mémoire, la méthode
Bitmap.createScaledBitmap()

0
michelmouton Messages postés 7 Date d'inscription samedi 23 août 2014 Statut Membre Dernière intervention 17 mars 2015
16 mars 2015 à 18:49
Salut :)
J'ai essayé de suivre ton conseil et ça ne marche pas beaucoup mieux ...
En revanche, j'ai suivi le Memory Monitor sur Android Studio et me suis rendu compte qu'à chaque nouvelle activité, 5 ou 6 mo étaient alloués en plus (or une image fait 40ko).
Et à partir d'un peu moins de 100 mo, l'application plante.

Mais le problème vient en réalité de la publicité admob que j'ai insérée. Aucun problème quand je désactive la pub.
Pour résoudre mon problème, je supprime manuellement à la fin de chaque activité l'objet AdView avec la méthode adView.destroy();

Et ça a l'air d'un peu mieux marcher. Mais je trouve tout de même bizarre que la Garbage Collector ne supprime pas les objets AdView à la fin d'une activité.

Voici le code correspondant à l'affichage de la pub :


adView = new AdView(this);
adView.setAdUnitId("ca-app-pub-******");
adView.setAdSize(AdSize.SMART_BANNER);
// Recherchez l'entité LinearLayout en supposant qu'elle est associée à
// l'attribut android:id="@+id/mainLayout".
RelativeLayout layout = (RelativeLayout)findViewById(R.id.pub);
// Ajoutez-y l'objet adView.
layout.addView(adView);
// Initiez une demande générique.
AdRequest adRequest = new AdRequest.Builder().build();
// Chargez l'objet adView avec la demande d'annonce.
adView.loadAd(adRequest);



Bref, tout cela est bien bizarre mais plus ou moins résolu.
0
BunoCS Messages postés 15475 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 23 avril 2024 3 894
17 mars 2015 à 09:01
Le GC n'est pas un outil magique: quand il fait son petit tour, il regarde ce qu'il peut récupérer = les objets qui n'ont plus de référence. Ici, ta pub était toujours attachée, donc il est normal de faire un destroy dessus:
https://developer.android.com/reference
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
michelmouton Messages postés 7 Date d'inscription samedi 23 août 2014 Statut Membre Dernière intervention 17 mars 2015
17 mars 2015 à 11:10
Effectivement, j'avais omis de faire ça.
Merci beaucoup pour votre aide :)
A bientôt !
0