1

I followed this answer from stackoverflow:

Lazy load of images in ListView

and the same from Github:

https://github.com/thest1/LazyList

where in the last line of Basic Usage, it says:

Please create only one instance of ImageLoader and reuse it all around your application. This way image caching will be much more efficient.

How can i do this?

I have lot of ListView(10-15) and so far i am using this way in the Adapter class, as given in the Example:

public ImageLoader imageLoader; 

    public LazyAdapter(Activity a, String[] d) {
        activity = a;
        data=d;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader=new ImageLoader(activity.getApplicationContext());
    }

I tried doing this:

Create a static variable in the first class, and use it everywhere else:

Class first{
public static ImageLoader imageLoader;
}

Class LazyAdapter{

first.imageLoader = new ImageLoader(activity.getApplicationContext());
//use it
}

But isn't this same as creating different instances? I mean i will be creating a new instance in every Adapter, of course the previous instance is gone(not more reference).

So, is this the right way to use?

EDIT:

Also this is written in the code:

public File getFile(String url){
    //I identify images by hashcode. Not a perfect solution, good for the demo.
    String filename=String.valueOf(url.hashCode());
    //Another possible solution (thanks to grantland)
    //String filename = URLEncoder.encode(url);
    File f = new File(cacheDir, filename);
    return f;

}

So, should i use String filename = URLEncoder.encode(url);??

and

//use 25% of available heap size

by heap size it mean RAM? or the MAX RAM that can be allocated to an Applcation (I read somewhere it is 19mb).

Because according to the Device(Samsung Galaxy GT-S5830) Specifications:

Internal- 158 MB storage, 278 MB RAM

But in log i get

01-23 06:23:45.679: I/MemoryCache(1712): MemoryCache will use up to 16.0MB

which is 25% as set in the code.

If it is like 25% of available memory. Then in Settings -> Applications -> Manage Applications:

At the bottom, it says 159MB used 21MB free.

ThankYou

Community
  • 1
  • 1
user1537779
  • 2,311
  • 5
  • 28
  • 45
  • You can use Application class to keep you static ImageLoader, and you can access that from any activity by getApplication().getImageLoader(); – Kapil Vats Feb 20 '13 at 07:11
  • There is a good library to lazy backgroud image loading that has singleton logic and a lot of other features out of the box. https://github.com/nostra13/Android-Universal-Image-Loader/wiki – TpoM6oH Feb 20 '13 at 07:20

4 Answers4

3

The Reason, Author mentioned to use Only one ImageLoader Class through out the application is as many time you create ImageLoader Class Instance then internally it creates MemoryCache Object which means 10 times ImageLoader instance then 10 times MemoryCache Objects. In the LazyList project, 1 MemoryCache Object reserves 1/4th of App Heap memory for images. So Here most of you app heap memory is exhausted due to many MemoryCache Instances. Here I have a solution for your problem is that to make MemoryCache class Singleton Class as in below code:

Change your constructor in the MemoryCache as private and do the following modifications.

private static MemoryCache mc;
    public static MemoryCache getMemoryCache()
    {
        if(mc==null)
        {
            mc = new MemoryCache();
        }
        return mc;
    }
    private MemoryCache(){
        //use 25% of available heap size
        setLimit(Runtime.getRuntime().maxMemory()/4);
    }
TNR
  • 5,839
  • 3
  • 33
  • 62
  • and instead of `memoryCache = new MemoryCache();` use `memoryCache = MemoryCache.getMemoryCache();` in the **ImageLoader Constructor** ??? – user1537779 Feb 20 '13 at 07:45
  • Also, can you please check the EDIT part of the question – user1537779 Feb 20 '13 at 07:53
  • @user1537779 what you mentioned in the first comment is correct. for the edit question, I can say that minimum Heap Memory for any android device is 16 MB, you might using some latest device so that it is showing 16MB used for images. There are devices with 16MB, 32MB,64MB and even 128MB(Tablets) Heap Memory . – TNR Feb 20 '13 at 08:40
1

You should use a singleton pattern or just initialize a static variable in some class and then use it everywhere.

public LazyAdapter(Activity a, String[] d) {
    activity = a;
    data=d;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    imageLoader= someClass.imageLoader;
}
TpoM6oH
  • 8,385
  • 3
  • 40
  • 72
0

why not user a Factory method to create a singleton?

try this code snippet in your ImageLoader.java:

private synchronized static ImageLoader instance;

private ImageLoader(Context context) {
    this.context = context;
    fileCache = new FileCache(context);
    executorService = Executors.newFixedThreadPool(5);
}

public synchronized static ImageLoader getInstance(Context context) {
    if (instance == null)
        instance = new ImageLoader(context);
    return instance;
}
thepoosh
  • 12,497
  • 15
  • 73
  • 132
0

You can do like:

public class ImageLoader {

    private static ImageLoader inst;
    private ImageLoader() {

    }

    public static ImageLoader getInstance() {
        if (inst == null)
            inst = new ImageLoader(Context);
        return inst;
    }
}

Whenever you want object for the ImageLoader, you just need call getInstance() method: ImageLoader.getInstance()

Paresh Mayani
  • 127,700
  • 71
  • 241
  • 295