web-dev-qa-db-ja.com

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

Java.lang.OutOfMemoryErrorを取得しているときは、ploadActivity.Java

行番号176は:

  Bitmap bm = BitmapFactory.decodeFile(strPath);

ログの表示:

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

Bitmapオブジェクトをリサイクルする必要があります。

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

Getビューの上記のコード行の後に、以下に記述されたコードを追加するだけです////今ビットマップをリサイクルすることで、すべての反復でメモリが解放されます

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

この後、同じエラーが発生している場合も、

以下のコードを置換

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

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

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

InSampleSizeを使用して、スケールビットマップをメモリにロードします。 inSampleSizeの値に2のべき乗を使用すると、デコーダーでより高速で効率的になります。ただし、サイズを変更したバージョンをメモリまたはディスクにキャッシュする場合は、通常、スペースを節約するために最適な画像サイズにデコードする価値があります。

詳細については、「読み込み 効率的な大きなビットマップ 」を参照してください

67
Shakeeb Ayaz

Applicationタグのマニフェストファイルでこれを使用します

Android:largeHeap="true"
11
Milan Pansuriya

ビットマップを呼び出す前bm = BitmapFactory.decodeFile(strPath);

これを呼び出します。Bitmap bm = decodeSampledBitmapFromResource(strPath、reqWidth、reqHeight);

再度Java.lang.OutOfMemoryErrorが発生した場合はお知らせください

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

これは、アプリケーションの最適化の問題です。 BitmapFactory.decodeFile(strPath)Android=はそのビットマップにメモリを割り当てようとしているため、システムが割り当てる十分な空き容量を見つけられないため、OutOfMemoryErrorが発生しています。このエラーが発生しています。

コードからわかるように、ImageAdapterを使用して画像のリストを表示しようとしています。その場合、imageviewは実際の画像よりも小さい幅と高さでなければなりません。

より一般化されたアイデアを提供するために、ここで何が起こっているのかを示します。

  • ImageViewの幅*高さ= 100dp * 100dp
  • 画像の幅*高さ= 800px * 800px。

このシナリオでは、imageviewのwidth-heightは100 * 100ですが、背景として800 * 800の画像を設定しようとしています。そして、これは間違いなく効率的な方法ではありません。なぜなら、システムは800 * 800ピクセルの画像にメモリを割り当てるのに対し、100 * 100はそうだからです。

そのため、ビットマップのデコードを行う前に、ビットマップをサンプリングして、100 * 100相当のメモリのみが割り当てられるようにする必要があります。

この説明のより詳細なバージョンがあります here

4
saiful103a

同じ問題がありました。上記のすべての提案を取り入れましたが、Java.lang.outOfMemoryErrorの問題がまだありました。多くの調整を行った後、最終的に機能したのは画像のサイズ(およびサイズ)の縮小でした。もともと、800 x 1000の次元の画像がありました。私はそれらを約60 x 80に再スケーリングし(それが必要だったので)、それはうまくいきました!

したがって、この問題についてstackoverflowや他のサイトで得られるすべてのアドバイスに従うことに加えて、画像のサイズと寸法の草の根チェックも行ってください。頭痛の種を大幅に減らします。

3
Rudra