1

java.lang.OutOfMemoryErrorの処理に問題があります:ビットマップサイズがVMバジェットエラーを超えています。元の画像が250x250pxより大きくなることはありません。ドローアブルフォルダからロードされます。インターネット上で「inJustDecodeBounds」について話している解決策をいくつか見つけましたが、それを機能させることができません。この問題を修正する方法について何かアイデアはありますか?それは私に2日間の頭痛を引き起こしています...

現在、親の幅に基づいて計算した係数で画像を再スケーリングしています。

@Override
    public View getView(int position, View v, ViewGroup parent) {
        View mView = v;
        this.parent = parent;

        if (mView == null) {

            LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
            mView = vi.inflate(R.layout.caa_xml, null);
        }

        ImageView image = (ImageView) mView.findViewById(R.id.iv_caarow);

        String name = getItem(position).getFile();
        int resId = C.getResources().getIdentifier(name, "drawable",
                "com.test.com");
        int imageWidth = (int) calculateImageWidth();
        // load the origial BitMap (250 x 250 px)
        Bitmap bitmapOrg = BitmapFactory
                .decodeResource(C.getResources(), resId);

        int width = bitmapOrg.getWidth();
        int height = bitmapOrg.getHeight();
        int newWidth = imageWidth;
        int newHeight = imageWidth;

        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;

        // create a matrix for the manipulation
        Matrix matrix = new Matrix();
        // resize 
        matrix.postScale(scaleWidth, scaleHeight);
        // recreate the new Bitmap
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, width,
                height, matrix, true);

        BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);

        image.setImageDrawable(bmd);

        if (mView != null) {

            //additional code here

        }
        return mView;
    }

    private float calculateImageWidth() {
        // TODO Auto-generated method stub
        int parentW = parent.getWidth() - parent.getPaddingLeft()
                - parent.getPaddingRight();
        Resources r = C.getResources();
        float pxPaddingBetweenItem = TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 2, r.getDisplayMetrics());
        float pxPaddingInItem = TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());

        int totalImageWidth = (parentW - (int) (3 * pxPaddingBetweenItem) - (int) (8 * pxPaddingInItem)) / 4;
        float imageWidth = (float) totalImageWidth;
        return imageWidth;
    }
4

1 に答える 1

3

問題は、古い大きなビットマップを使用してスケーリングされたビットマップを作成することです。その後、メモリに2つのビットマップがあり、古いビットマップをリサイクルすることもありません。

とにかく、より良い方法があります:

ImageView imageView = (ImageView) findViewById(R.id.some_id);
String pathToImage = "path";

BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathToImage, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;

// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/50, photoH/50);

// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;

Bitmap bitmap = BitmapFactory.decodeFile(pathToFile, bmOptions);
imageView.setImageBitmap(bitmap);

編集:

ファイルパスの代わりにリソースIDを使用する場合は、decodeResourceを使用して、次のように最後の部分を実行します。

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId, bmOptions);
imageView.setImageBitmap(bitmap);

そのコードがお役に立てば幸いです。

于 2012-12-24T10:00:51.597 に答える