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

时间:2015-10-14 13:19:12

标签: java android multithreading android-fragments android-asynctask

错误Occured white retriving Bitmap在AsyncTask进程中,Logcat日志如下, 请告诉我如何清除此错误 我是android的初学者帮助我 提前谢谢

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");
        }
    }

}

现在告诉我该怎么做......

3 个答案:

答案 0 :(得分:0)

显然你的方法doInBackground无法处理你的图像。你的应用程序中是否有其他图像处理?另外,我建议你使用它:

bitmap.recycle(); bitmap = null;

这将确保位图被垃圾收集。如果您不回收位图,则会出现内存不足异常

答案 1 :(得分:0)

不要在let tabButton = UIButton() let smallCircle = UIView() let largeCircle = UIView() required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.addSubview(tabButton) self.addSubview(smallCircle) self.addSubview(largeCircle) } override func layoutSubviews() { super.layoutSubviews() let height = self.frame.height tabButton.frame = CGRect(x: (self.frame.width-height)/2, y: 0, width: height, height: height) tabButton.backgroundColor = UIColor.greenColor() smallCircle.frame = CGRect(x: self.frame.width/2 - 2.5, y: height-10-8, width: 5, height: 5) smallCircle.backgroundColor = UIColor.blackColor() largeCircle.frame = CGRect(x: self.frame.width/2 - 5, y: height-8, width: 10, height: 10) largeCircle.backgroundColor = UIColor.redColor() print(smallCircle) print(largeCircle) } override func drawRect(rect: CGRect) { tabButton.layer.cornerRadius = tabButton.frame.width/2 } 内设置位图。而是返回新下载的doInBackground并仅在bitmap内设置。

您现在设置了onPostExecute两次,因此请在使用后从bitmapdoInBackground移除。

更新代码

recycle

答案 2 :(得分:0)

有效......

使用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");
        }
    }
}