0

Im caching my Bitmaps in GridView to LruCache. I made manager for this, see below:

private LruCache<String, Bitmap> mMemoryCache;

public LruCacheManager(){
    init();
}

private void init(){

    // Get max available VM memory, exceeding this amount will throw an
    // OutOfMemory exception. Stored in kilobytes as LruCache takes an
    // int in its constructor.
    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

    // Use 1/8th of the available memory for this memory cache.
    final int cacheSize = maxMemory / 8;

    //Log.i("ImageCache","cacheSize: " + cacheSize);
    if(mMemoryCache == null){
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in kilobytes rather than
                // number of items.
                // The cache size will be measured in kilobytes rather than
                // number of items.
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
                    return bitmap.getByteCount() ;
                } else {
                    return bitmap.getRowBytes() * bitmap.getHeight();
                }
            }

        };
    }


}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    if (getBitmapFromMemCache(key) == null) {
        Log.i("LruCacheManager","Bitmap is getting added, " + key);
        mMemoryCache.put(key, bitmap);
    }
}

public Bitmap getBitmapFromMemCache(String key) {
    return mMemoryCache.get(key);
}

when I call addBitmapToMemoryCache() in my AsyncTask to save Bitmaps to MemoryCache.

But when i call getBitmapFromMemoryCache() its null.

//get cached Bitmap
    LruCacheManager imCache = new LruCacheManager();
    String imageKey = categoryNames[position];
    Bitmap cachedBm = imCache.getBitmapFromMemCache(imageKey);

    //Decide whatever use cached image or not
    if (cachedBm != null) {
        Log.i("AdapterGridView","Using cached image, " + imageKey);
        viewHolder.icon.setImageBitmap(cachedBm);
    } else {
        //starts Asynctask to scale pictures and show them, happens off the main thread
        new AsyncTaskImageLoader(viewHolder.icon, imageKey, mContext, imCache, mThumbIds[position]).execute();
    }

Which means, AsyncTask is called again and again. In AsyncTask im adding the Bitmaps to LruCache. Because returned Bitmap is null, there is no Bitmap saved in LruCache. But i have no clue why. I also searched online and it has maybe to do something with recycling/Garbage Collector.

So how can i properly load cached images?

Any help or clarification is appriciate.

EDIT:

I call this inside BaseAdapter in getView() method. I think it has something to do with it. For the first time, each image is added to Cache, but then, the first image is added like 10 times.

Vojtěch Pešek
  • 1,070
  • 8
  • 25

1 Answers1

1

First I would set an arbitrary memory size and try with 1 image. The rest looks good... If what I have below doesn't work, give us printouts of your memory, etc. You might not have any.

In my version I get memory by

  final int maxMemory = (int) (Runtime.getRuntime().maxMemory());

then set it by a fraction ( I think I picked an 8th) I do the /1024 when I return get the size of, I do not do it for setting the memory. So if you have 1/1000 of the memory you think you have, that would be the likely issue..

StarWind0
  • 1,554
  • 2
  • 17
  • 46
  • as @StarWind0 says, that initial cache size is very low. Worked out to 16k on my device. Your bitmaps are probably getting auto-discarded – Kenneth Hippolite Feb 27 '18 at 16:12
  • Yeah me 3 years later would never use a fraction of max memory. I would down sample the images, then decide on how many I needed at minimum. – StarWind0 Feb 27 '18 at 20:13