web-dev-qa-db-fra.com

java.lang.OutOfMemoryError - BitmapFactory.decode (strPath)

Je reçois Java.lang.OutOfMemoryError , chaque fois que j'appelle ploadActivity.Java

Le numéro de ligne 176 est:

  Bitmap bm = BitmapFactory.decodeFile(strPath);

Voir mon journal:

12-07 17:57:10.585: E/AndroidRuntime(16708): FATAL EXCEPTION: main
12-07 17:57:10.585: E/AndroidRuntime(16708): Java.lang.OutOfMemoryError
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.graphics.BitmapFactory.decodeStream(BitmapFactory.Java:650)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.graphics.BitmapFactory.decodeFile(BitmapFactory.Java:389)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.graphics.BitmapFactory.decodeFile(BitmapFactory.Java:449)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at com.example.camera.UploadActivity$ImageAdapter.getView(UploadActivity.Java:176)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.AbsListView.obtainView(AbsListView.Java:2465)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.ListView.makeAndAddView(ListView.Java:1775)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.ListView.fillDown(ListView.Java:678)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.ListView.fillFromTop(ListView.Java:739)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.ListView.layoutChildren(ListView.Java:1628)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.AbsListView.onLayout(AbsListView.Java:2300)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.RelativeLayout.onLayout(RelativeLayout.Java:948)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.FrameLayout.onLayout(FrameLayout.Java:448)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1655)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1513)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1426)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.widget.FrameLayout.onLayout(FrameLayout.Java:448)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.ViewRootImpl.performLayout(ViewRootImpl.Java:1996)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.ViewRootImpl.performTraversals(ViewRootImpl.Java:1817)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.ViewRootImpl.doTraversal(ViewRootImpl.Java:1114)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.Java:4520)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.Choreographer$CallbackRecord.run(Choreographer.Java:725)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.Choreographer.doCallbacks(Choreographer.Java:555)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.Choreographer.doFrame(Choreographer.Java:525)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.Java:711)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.os.Handler.handleCallback(Handler.Java:615)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.os.Handler.dispatchMessage(Handler.Java:92)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.os.Looper.loop(Looper.Java:137)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Android.app.ActivityThread.main(ActivityThread.Java:4921)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Java.lang.reflect.Method.invokeNative(Native Method)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at Java.lang.reflect.Method.invoke(Method.Java:511)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1036)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:803)
12-07 17:57:10.585: E/AndroidRuntime(16708):    at dalvik.system.NativeStart.main(Native Method)

ploadActivity.Java:-

public class ImageAdapter extends BaseAdapter
        {
        private Context context;

        public ImageAdapter(Context c)
        {
        // TODO Auto-generated method stub
        context = c;
        }

        public int getCount() {
        // TODO Auto-generated method stub
        return ImageList.size();
        }

        public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
        }

        public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
        }

        public View getView(final int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        LayoutInflater inflater = (LayoutInflater) context
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);      

        if (convertView == null) {
        convertView = inflater.inflate(R.layout.list_upload, null);
        }


        // ColImgName
        TextView txtName = (TextView) convertView.findViewById(R.id.ColImgName);
        strPath = ImageList.get(position).toString();

        // Get File Name
        fileName = strPath.substring( strPath.lastIndexOf('/')+1, strPath.length() );
        File file = new File(strPath);
        @SuppressWarnings("unused")
        long length = file.length();
        txtName.setText(fileName);

        // Image Resource
        ImageView imageView = (ImageView) convertView.findViewById(R.id.ColImgPath);
        Bitmap bm = BitmapFactory.decodeFile(strPath);
        imageView.setImageBitmap(bm);


        // ColStatus
        final ImageView txtStatus = (ImageView) convertView.findViewById(R.id.ColStatus);
        txtStatus.setImageResource(R.drawable.bullet_button);

        // progressBar
        final ProgressBar progress = (ProgressBar) convertView.findViewById(R.id.progressBar);
        progress.setVisibility(View.GONE);

        //btnUpload
        final ImageButton btnUpload = (ImageButton) convertView.findViewById(R.id.btnUpload);
        btnUpload.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
        // Upload
        btnUpload.setEnabled(false);

        startUpload(position);
        }
        });

        return convertView;

        }
    } 
20
Sun

Vous devez recycler l'objet Bitmap.

    Bitmap bm = BitmapFactory.decodeFile(strPath);
    imageView.setImageBitmap(bm);

Après les lignes de code ci-dessus dans votre vue get, ajoutez simplement le code écrit ci-dessous /// recyclez maintenant votre bitmap, cela libérera de la mémoire à chaque itération

    if(bm!=null)
   {
     bm.recycle();
     bm=null;
    }

Après cela aussi si vous obtenez la même erreur le

Remplacer le code ci-dessous

    Bitmap bm = BitmapFactory.decodeFile(strPath);
    imageView.setImageBitmap(bm);

avec

 final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;

Bitmap bm = BitmapFactory.decodeFile(strPath,options);
imageView.setImageBitmap(bm);

Utilisez inSampleSize pour charger des images bitmap en mémoire. L'utilisation de puissances de 2 pour les valeurs inSampleSize est plus rapide et plus efficace pour le décodeur. Cependant, si vous prévoyez de mettre en cache les versions redimensionnées dans la mémoire ou sur le disque, cela vaut généralement la peine d'être décodé aux dimensions d'image les plus appropriées pour économiser de l'espace.

Pour plus d'informations, voir Chargement Grands bitmaps efficacement

67
Shakeeb Ayaz

Utilisez-le dans le fichier manifeste de la balise Application

Android:largeHeap="true"
11
Milan Pansuriya

avant d'appeler Bitmap bm = BitmapFactory.decodeFile (strPath);

appelez cela. Bitmap bm = decodeSampledBitmapFromResource (strPath, reqWidth, reqHeight);

si vous obtenez à nouveau Java.lang.OutOfMemoryError, faites le moi savoir

public static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;    
        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and
            // keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

public static Bitmap decodeSampledBitmapFromResource(String strPath,int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(strPath, options);
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options,reqWidth,
                reqHeight);
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(strPath, options);;
}
7
Santhosh

C'est un problème d'optimisation pour votre application. Vous obtenez OutOfMemoryError parce que lorsque vous effectuez BitmapFactory.decodeFile (strPath) Android essaie d'allouer de la mémoire pour ce bitmap. Dans votre cas, le système ne peut pas trouver suffisamment d'espace libre à allouer et c'est pourquoi vous obtenez cette erreur.

Maintenant, comme je peux le voir dans votre code, vous essayez d'afficher la liste des images à l'aide d'ImageAdapter. Dans ce cas, votre image doit avoir une largeur et une hauteur plus petites que l'image réelle.

Pour vous donner une idée plus généralisée, voici ce qui se passe:

  • ImageView largeur * hauteur = 100dp * 100dp
  • Largeur d'image * hauteur = 800 px * 800 px.

Dans ce scénario, bien que notre largeur d'image-hauteur soit de 100 * 100, mais nous essayons de définir l'image 800 * 800 comme arrière-plan. Et ce n'est certainement pas un moyen efficace car le système allouera de la mémoire pour une image de 800 * 800px alors que 100 * 100 le ferait.

C'est pourquoi, avant de décoder le bitmap, vous devez échantillonner le bitmap afin que seulement 100 * 100 de mémoire soient alloués.

Vous trouverez une version plus détaillée de cette explication ici

4
saiful103a

J'ai eu le même problème. J'ai incorporé toutes les suggestions ci-dessus, mais j'avais toujours le problème de Java.lang.outOfMemoryError. Après de nombreux ajustements, ce qui a finalement fonctionné a été de réduire les dimensions (et la taille) de l'image. À l'origine, j'avais des images de dimensions 800 x 1000 sortes. Je les ai redimensionnés à environ 60 x 80 (parce que c'est ce dont j'avais besoin), et cela a fonctionné!

Donc, en plus de suivre tous les conseils que vous obtenez sur stackoverflow et d'autres sites à ce sujet, faites également une vérification de base de vos tailles et dimensions d'image. Vous fera économiser beaucoup de maux de tête.

3
Rudra