解码位图流时的Android应用OutOfMemoryError

时间:2013-09-28 06:31:28

标签: android out-of-memory

我遇到了这个问题:OutOfMemoryError !!

以下是导致问题的屏幕:

enter image description here

当我使用鼠标向下滚动时。我的应用程序突然关闭,这是logcat显示的内容:

09-05 08:25:36.469: E/AndroidRuntime(8941): FATAL EXCEPTION: AsyncTask #5
09-05 08:25:36.469: E/AndroidRuntime(8941): java.lang.RuntimeException: An error occured while executing doInBackground()
09-05 08:25:36.469: E/AndroidRuntime(8941):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at java.lang.Thread.run(Thread.java:841)
09-05 08:25:36.469: E/AndroidRuntime(8941): Caused by: java.lang.OutOfMemoryError
09-05 08:25:36.469: E/AndroidRuntime(8941):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:530)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:603)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at com.ptit.piclient.tools.AllSongAdapter2$DownloadImageTask.doInBackground(AllSongAdapter2.java:91)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at com.ptit.piclient.tools.AllSongAdapter2$DownloadImageTask.doInBackground(AllSongAdapter2.java:1)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
09-05 08:25:36.469: E/AndroidRuntime(8941):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
09-05 08:25:36.469: E/AndroidRuntime(8941):     ... 4 more

它说问题是DownloadImageTask类。以下是该类的代码:

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>{
        ImageView imgView;
        public DownloadImageTask(ImageView img){this.imgView = img;}

        @Override
        protected Bitmap doInBackground(String... urls) {
            String urlDisplay = urls[0];
            Bitmap icon = null;
            InputStream in = null ;
            try {
                in = new URL(urlDisplay).openStream();
                icon = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //khuongdv start sep28
            finally{
                try {
                    in.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            //khuongdv end sep28
            return icon;
        }
        protected void onPostExecute(Bitmap result){
            if(result == null) return;
            imgView.setImageBitmap(result);
        }
    }

你能指出为什么会这样以及如何解决这个问题??

谢谢!

2 个答案:

答案 0 :(得分:1)

使用以下链接中的lazylist中的imageloader,它将帮助您从url加载图像,同时您可以显示临时图像。它还提供文件缓存,以便下次您不需要再次下载该图像时。

LazyList

在您要加载图片的任何地方使用以下代码。

ImageLoader imageLoader=new ImageLoader(this); imageLoader.displayImage(url,imageview);

并添加用户权限以写入外部存储空间使用文件缓存。

希望你发现它很有用......

答案 1 :(得分:0)

我认为懒惰列表不足以解决此问题。如果您是从磁盘加载,那么不是因为单个图像可能足以占用您的所有内存。

BitmapFactory具有仅解码标头的方法,因此您可以执行第二次通过解码,以缩小图像以避免此问题。但是,使用像Picasso之类的东西要简单得多,让它为你处理。