在AsyncTask进程中检索位图时发生错误



错误发生白色检索位图在AsyncTask过程中Logcat日志如下,请告诉我如何清除这个错误我是初学者,安卓帮我提前感谢

10-14 18:09:19.380  14124-16035/com.fragments D/dalvikvm﹕ GC_FOR_ALLOC freed 747K, 4% free 37438K/38855K, paused 191ms, total 193ms
10-14 18:09:19.400  14124-16035/com.fragments I/dalvikvm-heap﹕ Forcing collection of SoftReferences for 14155792-byte allocation
10-14 18:09:19.490  14124-16035/com.fragments D/dalvikvm﹕ GC_BEFORE_OOM freed 15K, 4% free 37422K/38855K, paused 91ms, total 91ms
10-14 18:09:19.490  14124-16035/com.fragments E/dalvikvm-heap﹕ Out of memory on a 14155792-byte allocation.
10-14 18:09:19.490  14124-16035/com.fragments I/dalvikvm﹕ "AsyncTask #4" prio=5 tid=16 RUNNABLE
10-14 18:09:19.490  14124-16035/com.fragments I/dalvikvm﹕ | group="main" sCount=0 dsCount=0 obj=0x432d6fc0 self=0x4d7c1fe8
10-14 18:09:19.490  14124-16035/com.fragments I/dalvikvm﹕ | sysTid=16035 nice=10 sched=3/0 cgrp=[fopen-error:2] handle=1300340400
10-14 18:09:19.490  14124-16035/com.fragments I/dalvikvm﹕ | schedstat=( 0 0 0 ) utm=15 stm=3 core=0
10-14 18:09:19.490  14124-16035/com.fragments I/dalvikvm﹕ at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
10-14 18:09:19.500  14124-16035/com.fragments I/dalvikvm﹕ at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:663)
10-14 18:09:19.500  14124-16035/com.fragments I/dalvikvm﹕ at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:735)
10-14 18:09:19.510  14124-16035/com.fragments I/dalvikvm﹕ at com.fragments.NewsListAdapter$ImageLoader.doInBackground(NewsListAdapter.java:128)
10-14 18:09:19.520  14124-16035/com.fragments I/dalvikvm﹕ at com.fragments.NewsListAdapter$ImageLoader.doInBackground(NewsListAdapter.java:112)
10-14 18:09:19.520  14124-16035/com.fragments I/dalvikvm﹕ at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-14 18:09:19.530  14124-16035/com.fragments I/dalvikvm﹕ at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
10-14 18:09:19.530  14124-16035/com.fragments I/dalvikvm﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:137)
10-14 18:09:19.530  14124-16035/com.fragments I/dalvikvm﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-14 18:09:19.530  14124-16035/com.fragments I/dalvikvm﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
10-14 18:09:19.530  14124-16035/com.fragments I/dalvikvm﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
10-14 18:09:19.530  14124-16035/com.fragments I/dalvikvm﹕ at java.lang.Thread.run(Thread.java:856)
10-14 18:09:19.530  14124-16035/com.fragments I/dalvikvm﹕ [ 10-14 18:09:19.530 14124:14133 W/SQLiteConnectionPool ]
A SQLiteConnection object for database '+data+data+com_fragments+databases+news_db' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
10-14 18:09:19.530  14124-14133/com.fragments D/AbsListView﹕ [unregisterDoubleTapMotionListener]
10-14 18:09:19.530  14124-14133/com.fragments I/MotionRecognitionManager﹕ .unregisterListener : / listener count = 0->0, ubvf 9budiwrd5ordgfl5BakTrklMrfo$,@,+)de/a(
10-14 18:09:19.560  14124-16035/com.fragments D/skia﹕ --- decoder->decode returned false
10-14 18:09:19.580  14124-16035/com.fragments W/dalvikvm﹕ threadid=16: thread exiting with uncaught exception (group=0x41ccd2b8)
10-14 18:09:19.740  14124-16035/com.fragments E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #4
java.lang.RuntimeException: An error occured while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:299)
        at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
        at java.util.concurrent.FutureTask.run(FutureTask.java:137)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
        at java.lang.Thread.run(Thread.java:856)
 Caused by: java.lang.OutOfMemoryError
        at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:663)
        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:735)
        at com.fragments.NewsListAdapter$ImageLoader.doInBackground(NewsListAdapter.java:128)
        at com.fragments.NewsListAdapter$ImageLoader.doInBackground(NewsListAdapter.java:112)
        at android.os.AsyncTask$2.call(AsyncTask.java:287)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
       10-14 18:09:28.740  14124-14124/com.fragments D/AndroidRuntime﹕ Shutting down VM
      10-14 18:09:28.740  14124-14124/com.fragments W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41ccd2b8)
     10-14 18:09:28.740  14124-14124/com.fragments I/Process﹕ Sending signal. PID: 14124 SIG: 9

更新:

这是我的AsyncTask类

    private class ImageLoader extends AsyncTask<NewsAndImages, Void, NewsAndImages> {
    @Override
    protected NewsAndImages doInBackground(NewsAndImages... params) {
        NewsAndImages container = params[0];
        News news = container.news;
        try {
            if (container.position > 0) {
                InputStream in = (InputStream) new URL(news.getImage150()).getContent();
                Bitmap bitmap = BitmapFactory.decodeStream(in);
                news.setBitmap(bitmap);
                in.close();
                container.bitmap = bitmap;
                return container;
            } else {
                InputStream in = (InputStream) new URL(news.getRealImage()).getContent();
                Bitmap bitmap = BitmapFactory.decodeStream(in);
                news.setBitmap(bitmap);
                in.close();
                container.bitmap = bitmap;
                return container;
            }
        } catch (Exception e) {
            Log.v("LOGTAG", e + " streaming pic"+news.getImage150());
        }
        return null;
    }
    @Override
    protected void onPostExecute(NewsAndImages newsAndImages) {
        try {
            if (newsAndImages.position > 0) {
            ImageView imageView = (ImageView) newsAndImages.view.findViewById(R.id.newsListImage);
            imageView.setImageBitmap(newsAndImages.bitmap);
            newsAndImages.news.setBitmap(newsAndImages.bitmap);
            }else {
                ImageView imageView = (ImageView) newsAndImages.view.findViewById(R.id.newsHeadLineImage);
                imageView.setImageBitmap(newsAndImages.bitmap);
                newsAndImages.news.setBitmap(newsAndImages.bitmap);
            }
        } catch (Exception e) {
            Log.v("LOGTAG", e + " post exe");
        }
    }
}

显然你的方法doInBackground不能处理你的图像。你的应用程序中还有其他图像处理吗?另外,我建议您使用以下命令:

bitmap.recycle(); bitmap = null;

这将确保位图被垃圾收集。如果你不回收你的位图你会有一个内存不足的异常

不要在doInBackground内设置位图。而不是返回新下载的bitmap,只在onPostExecute内设置。

你现在设置了bitmap两次,所以使用后从doInBackgroundrecycle中删除。

更新代码
 private class ImageLoader extends AsyncTask<String, Void, Bitmap> {
        @Override
        protected Bitmap doInBackground(NewsAndImages... params) {
            NewsAndImages container = params[0];
            News news = container.news;
            try {
                if (container.position > 0) {
                    InputStream in = (InputStream) new URL(news.getImage150()).getContent();
                    Bitmap bitmap = BitmapFactory.decodeStream(in);
                    in.close();
                    return bitmap;
                } else {
                    InputStream in = (InputStream) new URL(news.getRealImage()).getContent();
                    Bitmap bitmap = BitmapFactory.decodeStream(in);
                    in.close();
                    return bitmap;
                }
            } catch (Exception e) {
                Log.v("LOGTAG", e + " streaming pic"+news.getImage150());
            }
            return null;
        }
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            try {
                if (bitmap !=null) {
                ImageView imageView = (ImageView) newsAndImages.view.findViewById(R.id.newsListImage);
                imageView.setImageBitmap(bitmap);
                newsAndImages.news.setBitmap(bitmap);
                }else {
                    ImageView imageView = (ImageView) newsAndImages.view.findViewById(R.id.newsHeadLineImage);
                    imageView.setImageBitmap(bitmap);
                    newsAndImages.news.setBitmap(bitmap);
                }
                bitmap.recycle();
            } catch (Exception e) {
                Log.v("LOGTAG", e + " post exe");
            }
        }
    }

It Works…

使用LruCache

private class ImageLoader extends AsyncTask<NewsAndImages, Void, NewsAndImages> {
    @Override
    protected NewsAndImages doInBackground(NewsAndImages... params) {
        NewsAndImages container = params[0];
        News news = container.news;
        try {
            if (container.position > 0) {
                InputStream in = (InputStream) new URL(news.getImage150()).getContent();
                Bitmap bitmap = BitmapFactory.decodeStream(in);
                news.setBitmap(bitmap);
                in.close();
                container.bitmap = bitmap;
                return container;
            } else {
                InputStream in = (InputStream) new URL(news.getRealImage()).getContent();
                Bitmap bitmap = BitmapFactory.decodeStream(in);
                news.setBitmap(bitmap);
                in.close();
                container.bitmap = bitmap;
                return container;
            }
        } catch (Exception e) {
            Log.v("LOGTAG", e + " streaming pic" + news.getImage150());
        }
        return null;
    }
    @Override
    protected void onPostExecute(NewsAndImages newsAndImages) {
        try {
            if (newsAndImages.position > 0) {
                ImageView imageView = (ImageView) newsAndImages.view.findViewById(R.id.newsListImage);
                imageView.setImageBitmap(newsAndImages.bitmap);               
                imageCache.put(newsAndImages.news.getNews_id(),newsAndImages.bitmap);
            } else {
                ImageView imageView = (ImageView) newsAndImages.view.findViewById(R.id.newsHeadLineImage);
                imageView.setImageBitmap(newsAndImages.bitmap);
                imageCache.put(newsAndImages.news.getNews_id(),newsAndImages.bitmap);
            }
        } catch (Exception e) {
            Log.i(NewsDBOpenHelper.LOGTAG, e + " onPostExecute");
        }
    }
}

最新更新