【问题标题】:out of memory on a byte allocation, asynctask 5字节分配内存不足,异步任务 5
【发布时间】:2013-02-01 07:41:28
【问题描述】:

我正在尝试从“url”加载图像,该文件夹是我的 SD 卡中包含大约 40 张图像的文件夹到我的阅读器中,但我不断收到内存不足错误。有没有办法解决它?可能是因为我试图一次加载 40 张图片,这就是导致错误的原因吗?

下面是我的 logcat 输出

02-01 15:38:17.410: D/url(10695): /mnt/sdcard/Android/data/com.sfa.coverflow/Issues/20/1944628064
02-01 15:38:17.440: D/dalvikvm(10695): GC_FOR_ALLOC freed 7144K, 32% free 16978K/24711K, paused 23ms
02-01 15:38:17.440: I/dalvikvm-heap(10695): Forcing collection of SoftReferences for 33033616-byte allocation
02-01 15:38:17.460: D/dalvikvm(10695): GC_BEFORE_OOM freed 9K, 32% free 16969K/24711K, paused 25ms
02-01 15:38:17.460: E/dalvikvm-heap(10695): Out of memory on a 33033616-byte allocation.
02-01 15:38:17.460: I/dalvikvm(10695): "AsyncTask #5" prio=5 tid=17 RUNNABLE
02-01 15:38:17.460: I/dalvikvm(10695):   | group="main" sCount=0 dsCount=0 obj=0x411358f0 self=0x468d20
02-01 15:38:17.460: I/dalvikvm(10695):   | sysTid=10718 nice=10 sched=0/0 cgrp=bg_non_interactive handle=3779488
02-01 15:38:17.460: I/dalvikvm(10695):   | schedstat=( 48743000 7345000 28 ) utm=4 stm=0 core=1
02-01 15:38:17.460: I/dalvikvm(10695):   at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
02-01 15:38:17.460: I/dalvikvm(10695):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
02-01 15:38:17.460: I/dalvikvm(10695):   at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299)
02-01 15:38:17.460: I/dalvikvm(10695):   at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:324)
02-01 15:38:17.460: I/dalvikvm(10695):   at com.sfa.touchview.UrlTouchImageView$ImageLoadTask.doInBackground(UrlTouchImageView.java:108)
02-01 15:38:17.460: I/dalvikvm(10695):   at com.sfa.touchview.UrlTouchImageView$ImageLoadTask.doInBackground(UrlTouchImageView.java:1)
02-01 15:38:17.460: I/dalvikvm(10695):   at android.os.AsyncTask$2.call(AsyncTask.java:264)
02-01 15:38:17.460: I/dalvikvm(10695):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-01 15:38:17.460: I/dalvikvm(10695):   at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-01 15:38:17.460: I/dalvikvm(10695):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-01 15:38:17.460: I/dalvikvm(10695):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-01 15:38:17.460: I/dalvikvm(10695):   at java.lang.Thread.run(Thread.java:856)
02-01 15:38:17.460: D/skia(10695): --- decoder->decode returned false
02-01 15:38:17.470: W/dalvikvm(10695): threadid=17: thread exiting with uncaught exception (group=0x40a4f1f8)
02-01 15:38:17.470: E/AndroidRuntime(10695): FATAL EXCEPTION: AsyncTask #5
02-01 15:38:17.470: E/AndroidRuntime(10695): java.lang.RuntimeException: An error occured while executing doInBackground()
02-01 15:38:17.470: E/AndroidRuntime(10695):    at android.os.AsyncTask$3.done(AsyncTask.java:278)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at java.lang.Thread.run(Thread.java:856)
02-01 15:38:17.470: E/AndroidRuntime(10695): Caused by: java.lang.OutOfMemoryError
02-01 15:38:17.470: E/AndroidRuntime(10695):    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:324)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at com.sfa.touchview.UrlTouchImageView$ImageLoadTask.doInBackground(UrlTouchImageView.java:108)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at com.sfa.touchview.UrlTouchImageView$ImageLoadTask.doInBackground(UrlTouchImageView.java:1)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at android.os.AsyncTask$2.call(AsyncTask.java:264)
02-01 15:38:17.470: E/AndroidRuntime(10695):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-01 15:38:17.470: E/AndroidRuntime(10695):    ... 4 more

这是发生错误的地方

public class ImageLoadTask extends AsyncTask<String, Integer, Bitmap>
    {
        //RETRIEVES LINK FROM GALLERYACTIVITY
        //READ MNT/SDCARD/....

        @Override
        protected Bitmap doInBackground(String... strings) {
            bm = null;
            String url = strings[0];
            Log.d("url",url);

            bm = BitmapFactory.decodeFile(url);
            return bm;

        }

【问题讨论】:

    标签: android bitmap


    【解决方案1】:

    使用下面的代码调整位图的大小。

    例如,如果您在 300 * 300 的视图中加载分辨率为 1200 *800 的图像

    您可以使用decodeSampledBitmapFromResource(getResource(),R.drawable.mImage,300,300) 降低内存使用率。

    /**
         * 
         * get a resized bitmap
         * @param bm
         * @param newHeight
         * @param newWidth
         * @return
         */
        public static Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
            int width = bm.getWidth();
            int height = bm.getHeight();
            float scaleWidth = ((float) newWidth) / width;
            float scaleHeight = ((float) newHeight) / height;
            // create a matrix for the manipulation
            Matrix matrix = new Matrix();
            // resize the bitmap
            matrix.postScale(scaleWidth, scaleHeight);
            // "recreate" the new bitmap
            Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
                    matrix, false);
            return resizedBitmap;
        }
    
        /**
         * Decode a bitmap for avoiding out of memory issue
         * @param res
         * @param resId
         * @param reqWidth
         * @param reqHeight
         * @return
         */
        public static Bitmap decodeSampledBitmapFromResource(Resources res,
                int resId, int reqWidth, int reqHeight) {
    
            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeResource(res, resId, options);
    
            // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, reqWidth,
                    reqHeight);
            // Decode bitmap with inSampleSize set
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeResource(res, resId, options);
    
        }
    
        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) {
    
                // 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;
        }
    

    【讨论】:

    • 嗨,我如何准确地实现代码?对不起,我不擅长编程
    • 嗨,我已经实现了你的代码并做了 mImageView.setImageBitmap(getResizedBitmap(bm, 700, 500));但我仍然得到同样的错误:(
    • 不,您应该使用 decodeSampledBitmapResource 而不是 getResizedBitmap 如果您仍然遇到同样的问题,请尝试减小位图的大小,例如 decodeSampledBitmapFromResource(getResource(),R.drawable.mImage,100,100)
    【解决方案2】:

    你应该this关于加载位图的文章来避免这种情况。观看来自 Android 开发者的 video 也会很有用。

    【讨论】:

      猜你喜欢
      • 2014-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多