Mehul Ranpara
Mehul Ranpara

Reputation: 4255

OutOfMemory Error when loading big image from url

I am using lazyloading from this link to set image from url and i have very large bitmap.. In my listview there are many images to load and when i am scrolling the listview 20-30 times it's gives error of outofmemory.. how, can i solved this error..?

Upvotes: 0

Views: 927

Answers (4)

Raghunandan
Raghunandan

Reputation: 133560

Outof MemoryError

Thrown when a request for memory is made that can not be satisfied using the available platform resources. Such a request may be made by both the running application or by an internal function of the VM.

So your image is too large and it is exceeding the memory allocated by VM. Scale down the image or use the below libraries.

You can use

  1. Lazy List

  2. Universal Image Loader

Lazy List is lazy loading of images from sdcard or fomr server using urls. It is like on demand loading images.

Images can be cached to local sd card or phone mmeory. Url is considered the key. If the key is present in sdcard display images from sd card else display image by downloading from server and cache the same to location of your choice. The cache limit can set. You can also choose your own location to cache images. Cache can also be cleared.

Instead of user waiting to download large images and then displaying lazy list loads images on demand. Since images area cached you can display images offline.

https://github.com/thest1/LazyList. Lazy List

In your getview

 imageLoader.DisplayImage(imageurl, imageview);

ImageLoader Display method

public void DisplayImage(String url, ImageView imageView) //url and imageview as parameters
{
imageViews.put(imageView, url);
Bitmap bitmap=memoryCache.get(url);   //get image from cache using url as key
if(bitmap!=null)         //if image exists
    imageView.setImageBitmap(bitmap);  //dispaly iamge
 else   //downlaod image and dispaly. add to cache.
 {
    queuePhoto(url, imageView);
    imageView.setImageResource(stub_id);
 }

} An alternative to Lazy List is Universal Image Loader

https://github.com/nostra13/Android-Universal-Image-Loader. It is based on Lazy List(works on same principle). But it has lot of other configurations. I would prefer to use Universal Image Loader coz it gives you more configuration options. You can display a error image if downlaod failed. Can display images with rounded corners. Can cache on disc or memory. Can compress image.

In your custom adapter constructor

  File cacheDir = StorageUtils.getOwnCacheDirectory(a, "your folder");

  // Get singletone instance of ImageLoader
  imageLoader = ImageLoader.getInstance();
  // Create configuration for ImageLoader (all options are optional)
  ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
      // You can pass your own memory cache implementation
     .discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
     .discCacheFileNameGenerator(new HashCodeFileNameGenerator())
     .enableLogging()
     .build();
   // Initialize ImageLoader with created configuration. Do it once.
   imageLoader.init(config);
   options = new DisplayImageOptions.Builder()
   .showStubImage(R.drawable.stub_id)//display stub image
   .cacheInMemory()
   .cacheOnDisc()
   .displayer(new RoundedBitmapDisplayer(20))
   .build();

In your getView()

   ImageView image=(ImageView)vi.findViewById(R.id.imageview); 
   imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options

You can configure with other options to suit your needs.

This what the author has to say.(Straight from the link under the topic Useful info)

If you often get OutOfMemoryError in your app using Universal Image Loader then try next (all of them or several):

  1. Reduce thread pool size in configuration (.threadPoolSize(...)). 1 - 5 is recommended. Use .bitmapConfig(Bitmap.Config.RGB_565) in display options. Bitmaps in RGB_565 consume 2 times less memory than in ARGB_8888.

  2. Use .memoryCache(new WeakMemoryCache()) in configuration or disable caching in memory at all in display options (don't call .cacheInMemory()).

  3. Use .imageScaleType(ImageScaleType.IN_SAMPLE_INT) in display options. Or try .imageScaleType(ImageScaleType.EXACTLY).

  4. Avoid using RoundedBitmapDisplayer. It creates new Bitmap object with ARGB_8888 config for displaying during work.

Along with lazy loading/Universal Image Loader you can use view holder for smooth scrolling and performance.

http://developer.android.com/training/improving-layouts/smooth-scrolling.html.

Upvotes: 1

FoamyGuy
FoamyGuy

Reputation: 46856

You need to make sure that you are down-sampling when possible and since you are using a ListView you'll also potentially gain benefit by caching your images in memory, or on disk.

Read the best practices here: Displaying Bitmaps Effeciently

If you are looking for an easier way to implement the best practices consider using helper library for loading your images. Here is a nice one: Android-Universal-ImageLoader

Upvotes: 1

kyogs
kyogs

Reputation: 6836

Check this library for lazy loading Android-Universal-Image-Loader. This library provide a reusable instrument for asynchronous image loading, caching and displaying. It is originally based on lazyloading project and has been vastly refactored and improved since then.

Upvotes: 0

rgksugan
rgksugan

Reputation: 3582

This error occurs, because the image is huge. You can handle it efficiently through the method mentioned below.

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Upvotes: 0

Related Questions