Je veux afficher l’image Bitmap dans ImageView à partir de la carte SD déjà stockée. Après exécution, mon application plante et obtient l’erreur OutOfMemoryError de:
(java.lang.OutOfMemoryError: Échec d’allocation d’une allocation d’octets 23970828 avec 2097152 octets libres et 2 Mo jusqu’au MOO)
Je n’ai aucune idée ou pourquoi il est hors de mémoire. Je pense que la taille de mon image est très grande, alors j’ai essayé de la changer.
Iterator it = imageArray.iterator(); while (it.hasNext()) { Object element = it.next(); Ssortingng objElement = element.toSsortingng(); Log.e("objElement ", " = " + objElement); final ImageView imageView = new ImageView (getContext()); final ProgressBar pBar = new ProgressBar(getContext(), null, android.R.attr.progressBarStyleSmall); imageView.setTag(it); pBar.setTag(it); imageView.setImageResource(R.drawable.img_placeholder); pBar.setVisibility(View.VISIBLE); if (objElement.endsWith(mp3_Pattern)) { Log.e("Mp3 ", " ends with "); pBar.setVisibility(View.GONE); imageView.setImageResource(R.drawable.audio_control); } if (objElement.endsWith(png_Pattern)) { Bitmap bitmap = BitmapFactory.decodeFile(objElement); int size = Math.min(bitmap.getWidth(), bitmap.getHeight()); int x = (bitmap.getWidth() - size) / 2; int y = (bitmap.getHeight() - size) / 2; Bitmap bitmap_Resul = Bitmap.createBitmap(bitmap, x, y, size, size); Log.e("bitmap_Resul "," = "+ bitmap_Resul); if (bitmap_Resul != bitmap) { bitmap.recycle(); } imageView.setImageBitmap(bitmap_Resul); Log.e("png_Pattern ", " ends with "); Log.e(" bitmap "," = " + bitmap); } holder.linearLayout.addView(imageView); holder.linearLayout.addView(pBar);
L’information de chat de journal:
08-27 14:11:15.307 1857-1857/? E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.example.tazeen.classnkk, PID: 1857 java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.Bitmap.nativeCreate(Native Method) at android.graphics.Bitmap.createBitmap(Bitmap.java:812) at android.graphics.Bitmap.createBitmap(Bitmap.java:789) at android.graphics.Bitmap.createBitmap(Bitmap.java:709) at android.graphics.Bitmap.createBitmap(Bitmap.java:634) at com.example.tazeen.classnkk.AllPosts_Page$MyListAdapter.getView(AllPosts_Page.java:357) at android.widget.AbsListView.obtainView(AbsListView.java:2347) at android.widget.ListView.makeAndAddView(ListView.java:1864) at android.widget.ListView.fillDown(ListView.java:698) at android.widget.ListView.fillFromTop(ListView.java:759) at android.widget.ListView.layoutChildren(ListView.java:1659) at android.widget.AbsListView.onLayout(AbsListView.java:2151) at android.view.View.layout(View.java:15671) at android.view.ViewGroup.layout(ViewGroup.java:5038) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557) at android.widget.LinearLayout.onLayout(LinearLayout.java:1466) at android.view.View.layout(View.java:15671) at android.view.ViewGroup.layout(ViewGroup.java:5038) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579) at android.widget.FrameLayout.onLayout(FrameLayout.java:514) at android.view.View.layout(View.java:15671) at android.view.ViewGroup.layout(ViewGroup.java:5038) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557) at android.widget.LinearLayout.onLayout(LinearLayout.java:1466) at android.view.View.layout(View.java:15671) at android.view.ViewGroup.layout(ViewGroup.java:5038) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579) at android.widget.FrameLayout.onLayout(FrameLayout.java:514) at android.view.View.layout(View.java:15671) at android.view.ViewGroup.layout(ViewGroup.java:5038) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2086) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1843) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:550) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5257) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
OutOfMemoryError est le problème le plus courant survenu dans Android, en particulier en ce qui concerne les bitmaps. Cette erreur est provoquée par la machine virtuelle Java (JVM) lorsqu’un object ne peut pas être alloué en raison d’un manque d’espace mémoire et que le ramasse-miettes ne peut pas libérer de l’espace.
Comme mentionné par Aleksey, vous pouvez append des entités ci-dessous dans votre fichier manifeste android:hardwareAccelerated="false"
, android:largeHeap="true"
cela fonctionnera pour certains environnements.
Vous devriez certainement lire certains des concepts d’Androids Developer, spécialement ici: Affichage efficace des bitmaps
Lisez tous les 5 sujets et réécrivez votre code à nouveau. Si cela ne fonctionne toujours pas, nous serons heureux de voir ce que vous avez fait de mal avec le didacticiel.
Voici quelques réponses possibles à ce type d’erreurs dans SOF
Android: BitmapFactory.decodeStream () manque de mémoire avec un fichier de 400 Ko avec 2 Mo de mémoire libre
Comment résoudre les problèmes java.lang.OutOfMemoryError dans Android
Android: java.lang.OutOfMemoryError
java.lang.OutOfMemoryError
Solution pour OutOfMemoryError: la taille de l’image bitmap dépasse le budget de la machine virtuelle
Edit: D’après les commentaires de @cjnash
Pour ceux qui ont encore des pannes après avoir ajouté cette ligne, essayez de coller votre image dans votre dossier res / drawable-xhdpi / au lieu de votre res / drawable / et cela pourrait résoudre votre problème.
Avez-vous essayé d’append ceci à votre manifeste sous les applications? android:largeHeap="true"
?
comme ça
En fait, vous pouvez append dans votre manifeste ces lignes android:hardwareAccelerated="false"
, android:largeHeap="true"
cela fonctionne pour certaines situations, mais sachez que l’autre partie du code peut discuter avec cela.
Pour moi, le problème était que mon fichier .png était en train d’être décompressé pour devenir un bitmap vraiment énorme en mémoire, car l’image avait de très grandes dimensions (même si la taille du fichier était minuscule).
Donc le correctif était de simplement redimensionner l’image 🙂
Cela devrait fonctionner
BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 8; mBitmapInsurance = BitmapFactory.decodeFile(mCurrentPhotoPath,options);
Redimensionnez votre image avant de l’installer dans ImageView comme ceci:
Bitmap.createScaledBitmap(_yourImageBitmap, _size, _size, false);
où la taille est la taille réelle de ImageView. Vous pouvez atteindre la taille en mesurant:
imageView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
et utilisez la taille suivante imageView.getMeasuredWidth()
et imageView.getMeasuredHeight()
pour la scaling
à l’ scaling
.
Utilisez la taille Glide Library et Override pour réduire la taille;
Glide.with(mContext).load(imgID).asBitmap().override(1080, 600).into(mImageView);
J’ai résolu ce problème en redimensionnant l’image à une taille inférieure. J’utilise la forme xamarin. la diminution de la taille de l’image PNG a résolu le problème.
J’ai eu moins d’erreur
“E / art: Throwing OutOfMemoryError” Impossible d’allouer une allocation 47251468 octets avec 16777120 octets libres et 23 Mo jusqu’au MOO ”
après avoir ajouté android:largeHeap="true"
dans AndroidManifest.xml alors je me suis débarrassé de toutes les erreurs
Soluton essayez ceci dans votre fichier manifeste et utilisez la bibliothèque Glide
comstackr ‘com.github.bumptech.glide: glide: 3.7.0’
**Use Glide Library and Override size to less size;** if (!TextUtils.isEmpty(message.getPicture())) { Glide.with(mContext).load(message.getPicture()) .thumbnail(0.5f) .crossFade() .transform(new CircleTransform(mContext)) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(holder.imgProfile); }
android: hardwareAccelerated = “false”
android: largeHeap = “true”
Utilisez cette bibliothèque
comstack 'com.github.bumptech.glide:glide:3.7.0'
Son fonctionnement codage heureux
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Paint; import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; public class CircleTransform extends BitmapTransformation { public CircleTransform(Context context) { super(context); } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return circleCrop(pool, toTransform); } private static Bitmap circleCrop(BitmapPool pool, Bitmap source) { if (source == null) return null; int size = Math.min(source.getWidth(), source.getHeight()); int x = (source.getWidth() - size) / 2; int y = (source.getHeight() - size) / 2; // TODO this could be acquired from the pool too Bitmap squared = Bitmap.createBitmap(source, x, y, size, size); Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888); if (result == null) { result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(result); Paint paint = new Paint(); paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP)); paint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, paint); return result; } @Override public Ssortingng getId() { return getClass().getName(); } }
Problème: Échec d’allocation d’une allocation d’octets 37748748 avec les octets libres 16777120 et 17 Mo jusqu’à l’obtention d’un MOO
Solution: 1. Ouvrez votre fichier manifeste 2. À l’intérieur de la balise d’application, ajoutez simplement deux lignes
android:hardwareAccelerated="false" android:largeHeap="true"
Exemple :
J’ai aussi eu le problème.
Même avec la plupart des autres ci-dessus. Le problème est causé par une image énorme.
Il suffit de redimensionner certaines images et de ne changer aucun code.
Je suis un débutant dans le développement Android, mais j’espère que ma solution aide, cela fonctionne parfaitement sur ma condition. Im utilise Imageview et définir son arrière-plan à “src”, car je tente de faire une animation de trame. J’ai eu la même erreur mais quand j’ai essayé de coder cela a fonctionné
int ImageID = this.Resources.GetIdentifier(questionPlay[index].Image.ToLower(), "anim", PackageName); imgView.SetImageResource(ImageID); AnimationDrawable animation = (AnimationDrawable)imgView.Drawable; animation.Start(); animation.Dispose();
Dans certains cas (par exemple, les opérations en boucle), le garbage collector est plus lent que votre code. Vous pouvez utiliser une méthode d’assistance à partir de cette réponse pour attendre le garbage collector .
Je me suis heurté à ce problème quand je n’ai pas éliminé mon ancienne activité lors d’une nouvelle activité. Je l’ai corrigé avec finish();
Intent goToMain = new Intent(this,MainActivity.class); startActivity(goToMain); finish();
Cela a fonctionné pour moi: il suffit de déplacer les images du dossier pouvant être dessiné vers drawable-hdpi.
Bitmap image =((BitmapDrawable)imageView1.getDrawable()).getBitmap(); ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG,50/100,byteArrayOutputStream);
50/100 si on utilise 100 alors la résolution d’origine peut arrêter les applications pour mémoire.
si 50 ou moins de 100, ce sera 50% ou moins de 100 résolution, donc cela évitera un problème de mémoire insuffisante
J’ai trouvé que les images dans le dossier “drawable” seront converties en une image beaucoup plus grande sur les téléphones haute définition. Par exemple, une image de 200k sera ré-échantillonnée à une résolution supérieure, comme 800k ou 32000k. J’ai dû le découvrir seul et à ce jour, je n’ai pas vu la documentation de ce piège de mémoire de tas. Pour éviter cela, je mets tout dans un dossier drawable-nodpi (en plus de l’utilisation des options dans BitmapFactory en fonction du segment de mémoire particulier). Je ne peux pas me permettre de gonfler la taille de mon application avec plusieurs dossiers pouvant être dessinés, d’autant plus que la gamme de defs d’écran est maintenant si vaste. La chose la plus délicate étant que le studio n’indique pas spécifiquement le dossier ‘drawable-nodpi’ en tant que tel dans la vue du projet, il affiche simplement un dossier ‘pouvant être dessiné’. Si vous ne faites pas attention, lorsque vous déposez une image dans ce dossier en studio, elle ne sera pas réellement insérée dans le fichier dessin-nodpi:
Careful here 'backgroundtest' did not actually go to drawable-nodpi and will be resampled higher, such as 4x or 16x of the original dimensions for high def screens.
Assurez-vous de cliquer sur le dossier nodpi dans la boîte de dialog, car la vue du projet ne vous montrera pas tous les dossiers pouvant être dessinés séparément, de sorte qu’il ne sera pas immédiatement évident que celui-ci est incorrect. Studio a recréé la “vanille” de la vanille à un moment donné après l’avoir supprimée il y a longtemps:
Vous devez changer la taille de l’object dans drawable. C’est trop gros pour qu’Android l’affiche. Par exemple, si vous définissez une image, essayez l’image avec moins de pixels. Ça marche pour moi. Merci. 🙂
Si vous téléchargez une image, essayez de réduire la qualité de l’image, qui est le deuxième paramètre de la bitmap. C’était la solution dans mon cas. Auparavant, il était de 90, puis j’ai essayé avec 60 (comme dans le code ci-dessous maintenant).
Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream); ByteArrayOutputStream baos = new ByteArrayOutputStream(); finalBitmap.compress(Bitmap.CompressFormat.JPEG,60,baos); byte[] b = baos.toByteArray();
Essayez le plus simple. Peut-être que votre application se bloque parce que la taille de votre image (en Mo) est trop importante, de sorte qu’elle n’alloue pas d’espace pour cela. Donc, avant de coller votre image dans un tableau, réduisez simplement la taille de n’importe quel logiciel de visionneuse ou, si vous prenez une image de la galerie au moment de l’exécution, avant de l’enregistrer, compressez votre bitmap. Cela a fonctionné pour moi. certainement pour vous sera.
Votre application se bloque parce que la taille de votre image (en Mo ou en Ko) est trop importante, de sorte qu’elle n’atsortingbue pas d’espace pour cela. Donc, avant de coller votre image dans le dessin, réduisez simplement la taille.
OU
Vous pouvez append la suite dans la balise d’application à Manifest.xml
android:hardwareAccelerated="false" android:largeHeap="true" android:allowBackup="true"
Après l’ajout de cette application ne sera pas écrasé.
Mon problème résolu après l’ajout
dexOptions { incremental true javaMaxHeapSize "4g" preDexLibraries true dexInProcess = true }
dans le fichier Build.Gradle