Listview中的图像内存不足

时间:2014-01-10 23:24:10

标签: android listview android-asynctask

我的应用程序包含listview,其中包含2个textview和从json下载的imageview,我在网络课上找到了ImageDownload但是现在当我启动应用程序时它会加载项目,但是滚动速度很慢,而且越野车和力量关闭。第二件事是当我向下滚动并返回顶部,图像再次重新加载。我发现问题是内存不足,我必须缩小位图。但我不明白它是如何运作的,我无法做到。

ImageDownloadTask

 public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
FeedItem feed;
BitmapFactory bm;

    private final WeakReference<ImageView> imageViewReference;

    public ImageDownloaderTask(ImageView imageView) {
   imageViewReference = new WeakReference<ImageView>(imageView);



    }

    @Override
    // Actual download method, run in the task thread
    protected Bitmap doInBackground(String... params) {
     // params comes from the execute() call: params[0] is the url.
     return downloadBitmap(params[0]);
    }

    @Override
    // Once the image is downloaded, associates it to the imageView
    protected void onPostExecute(Bitmap bitmap) {
    if (isCancelled()) {
                    bitmap = null;
     }

      // Get current dimensions
       int width = bitmap.getWidth();
      int height = bitmap.getHeight();

       // Determine how much to scale: the dimension requiring
                        // less scaling is.
       // closer to the its side. This way the image always 
                        // stays inside your.
       // bounding box AND either x/y axis touches it.
      float xScale = ((float) width) / width;
     float yScale = ((float) height) / height;
     float scale = (xScale <= yScale) ? xScale : yScale;

     // Create a matrix for the scaling and add the scaling data
     Matrix matrix = new Matrix();
      matrix.postScale(scale, scale);

      // Create a new bitmap and convert it to a format understood

       // by the
          // ImageView
      Bitmap scaledBitmap = Bitmap.
      createBitmap(bitmap, 0, 0, width, height,
       matrix, true);




       if (imageViewReference != null) {
       ImageView imageView = imageViewReference.get();
      if (imageView != null) {

        if (bitmap != null) {
          imageView.setImageBitmap(scaledBitmap);

          } else {  

     imageView.setImageDrawable( imageView.getContext().getResources().getDrawable(R.drawable.list_placeholder));
                            }
                    }

            }
    }

    static Bitmap downloadBitmap(String url) {
  if(URLUtil.isValidUrl(url)){

     BitmapFactory.Options options = new BitmapFactory.Options();

      options.inJustDecodeBounds = true;

    options.inScaled = false;
     options.inPurgeable = true;
     options.inInputShareable = true;




     int imageHeight = options.outHeight;
     int imageWidth = options.outWidth;
     String imageType = options.outMimeType;

     final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
        final HttpGet getRequest = new HttpGet(url);
         try {
        HttpResponse response = client.execute(getRequest);
      final int statusCode = response.getStatusLine().getStatusCode();
       if (statusCode != HttpStatus.SC_OK) {
        Log.w("ImageDownloader", "Error " + statusCode
      + " while retrieving bitmap from " + url);
     return null;
   }

      final HttpEntity entity = response.getEntity();

      if (entity != null) {
     InputStream inputStream = null;
       try {
     inputStream = entity.getContent();
    final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
       return bitmap;
        } finally {
        if (inputStream != null) {
         inputStream.close();
        }
       entity.consumeContent();
      }
     }
     } catch (Exception e) {
    // Could provide a more explicit error message for IOException or
    // IllegalStateException
    getRequest.abort();
  Log.w("ImageDownloader", "Error while retrieving bitmap from " + url);
    } finally {
    if (client != null) {
     client.close();
  }
}
return null;

 }
return null;
}

}

错误

threadid=14: thread exiting with uncaught exception (group=0x4182b2a0)
FATAL EXCEPTION: AsyncTask #1
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

2 个答案:

答案 0 :(得分:1)

所以你会遇到一些你最初没想过的事情,所以我建议使用一个由已经不得不弄明白的人建造的图书馆。试试picasso

答案 1 :(得分:1)

This is a little old,但它仍然有助于显示您的方法有什么问题。

另外this SO tread goes over all the different approaches.

最后,让我强烈推荐Google's REST library called Volley

编辑我刚刚找到了this too,它比较了几个REST库的优缺点,包括okHTTP和Volley。