BaseAdapter Out of Memory错误

问题描述 投票:0回答:3

我将使用下面的代码从服务器(URL)加载Adapter的图像。它是新型移动设备的工作。然而,旧模型将崩溃并返回“java.lang.OutOfMemoryError”。它会将A行或B行标记为错误。如何避免这个错误?或者还有其他图书馆来完成我的目标吗?请帮忙,谢谢!

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;
    ProgressBar progressBar;

    public DownloadImageTask(ImageView bmImage, ProgressBar progressBar) {
        this.bmImage = bmImage;
        this.progressBar = progressBar;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon11 = null;
        try {



            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in); //Line A

            int resultWidth = mIcon11.getWidth();
            int resultHeight = mIcon11.getHeight();
            while(resultWidth > 256 && resultHeight > 256) {
                resultWidth *= 0.5;
                resultHeight *= 0.5;
            }
            mIcon11 = Bitmap.createScaledBitmap(mIcon11, (int) (resultWidth), (int) (resultHeight), true);

        } catch (OutOfMemoryError e){

            byte[] byteArr = new byte[0];
            byte[] buffer = new byte[1024];
            int len;
            int count = 0;


            InputStream in = null;
            try {
                in = new java.net.URL(urldisplay).openStream();


                while ((len = in.read(buffer)) > -1) {
                    if (len != 0) {
                        if (count + len > byteArr.length) {
                            byte[] newbuf = new byte[(count + len) * 2]; //Line B
                            System.arraycopy(byteArr, 0, newbuf, 0, count);
                            byteArr = newbuf;
                        }

                        System.arraycopy(buffer, 0, byteArr, count, len);
                        count += len;
                    }
                }


                final BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeByteArray(byteArr, 0, count, options);

                options.inSampleSize = calculateInSampleSize(options, 256, 256);
                options.inPurgeable = true;
                options.inInputShareable = true;
                options.inJustDecodeBounds = false;
                options.inPreferredConfig = Bitmap.Config.ARGB_8888;


                mIcon11 = BitmapFactory.decodeByteArray(byteArr, 0, count, options);

            } catch (IOException e1) {
                e1.printStackTrace();
            }

        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }



        return mIcon11;
    }

    protected void onPostExecute(Bitmap result) {

        bmImage.setImageBitmap(result);

        progressBar.setVisibility(View.GONE);
        progressBar.setIndeterminate(false);
        bmImage.setVisibility(View.VISIBLE);

    }


    public 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) {

            // Calculate ratios of height and width to requested height and width
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value, this will guarantee
            // a final image with both dimensions larger than or equal to the
            // requested height and width.
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }


        return inSampleSize;
    }

}
java android out-of-memory
3个回答
1
投票

你可以使用GLIDE

阅读有关Loading Large Bitmaps的官方指南。你应该RESIZE图像。

要避免使用java.lang.OutOfMemory异常,请在解码之前检查位图的尺寸,除非您完全信任该源为您提供可预测大小的图像数据,这些数据可以轻松地放入可用内存中。

代码结构

  • 从原件向下采样的位图,具有相同的宽高比和尺寸,等于或大于请求的宽度和高度
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;
}

0
投票

高分辨率位图的问题。您将减小大小或使用某些库进行位图加载,如Glide或Picasso。快速修复 - 您将在AndroidManifest中启用大堆:

<application 
         ...
         android:largeHeap="true"

0
投票

将此添加到您的gradle中

android   
{
  dexOptions
 {
       javaMaxHeapSize "4g" //specify the heap size for the dex process

  }
}
© www.soinside.com 2019 - 2024. All rights reserved.