Sandra Mladenovic
Sandra Mladenovic

Reputation: 202

Images in Listview out of memory

My app contains listview with 2 textviews and imageview downloaded from json, i have found on internet class for ImageDownload but now when i start app it loads the items, but scrolling is slow and buggy and force closes.Second thing is when i scroll down and turn back on top, images being reloaded again. And i have found that problem is out of memory and i have to scale down the bitmap. But i don't understand how really works and i can't do it.

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

}

Error

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

Upvotes: 1

Views: 148

Answers (2)

soundsofpolaris
soundsofpolaris

Reputation: 596

This is a little old, but it still will help show what' wrong with your approach.

Also this SO tread goes over all the different approaches.

Finally, let me strongly recommend Google's REST library called Volley

EDIT I just found this too, which compares the pro and cons of several REST libraries, including okHTTP and Volley.

Upvotes: 1

Larry McKenzie
Larry McKenzie

Reputation: 3283

So you will encounter several things you wouldn't initially think about when doing this so I recommend using a library that was built by people who have already had to figure it out. Try picasso!

Upvotes: 1

Related Questions