LruCache not working
Asked Answered
B

3

7
    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    final int cacheSize = maxMemory / 8;
    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.
                return bitmap.getByteCount() / 1024;
            }
        };
    URL url = new URL("http://s2.goodfon.ru/image/260463-1920x1200.jpg");
    Bitmap bitmap = BitmapFactory.decodeStream((InputStream) url.getContent(), null, options);
    if(bitmap != null)
        Log.i("Success", "BITMAP IS NOT NULL");

    String key = "myKey";
    Log.i("Get is null", "putting myKey");
    mMemoryCache.put(key, bitmap);

    Bitmap newBitmap = mMemoryCache.get(key);
    if(newBitmap == null)
        Log.i("newBitmap", "is null");

Hello, here is a code. I get bitmap from URL successfully (Log says Bitmap is not null and I can display it easy). Then I am trying to put it into LruCache and get it back, but it return null. (Log says newBitmap is null). Where is my mistake? Please, tell me. Android 4.1.2 Cache size 8192 Kb.

Balcom answered 17/3, 2013 at 10:39 Comment(3)
So, have you tried, that your calculation for the cache size is correct? And what does sizeOf() output? Are you sure the image is really inside the cache?Daryn
developer.android.com/training/displaying-bitmaps/….Estimable
Oh that image was 9000 kb, I thought its 1.19 mb as a file. Problem solved. Thank you. Plaese tell me, why 1.19 mb file returns 9000 kb in getByteCount / 1024?Balcom
G
8

If it is 1.19 MB on disk but ~ 9 MB in memory, that means that as a compressed JPEG file, it's 1.19 MB and once you extract that into a Bitmap (uncompressed) that can be displayed, it will take up 9 MB in memory. If it's a 1920 x 1200 pixel image as suggested by the url in your code snippet, the image will take up 1920 x 1200 x 4 bytes of memory (4 bytes for each pixel to represent ARGB values from 0 to 256 times 2.3 million total pixels = 9,216,000 bytes). If you're using 1/8 of your available memory for this cache, it's possible/likely that 9MB exceeds that total memory space so the Bitmap never makes it into the cache or is evicted immediately.

You're probably going to want to downsample the image at decoding time if it's that large (using BitmapFactory.Options.inSampleSize...lot's of documentation on the web for using that if you're not already familiar).

Also, you're using Runtime.maxMemory to compute your cache size. This means you're requesting the maximum amount of memory that the whole VM is allowed to use.

http://developer.android.com/reference/java/lang/Runtime.html#maxMemory%28%29

The more common approach is the use the value given back to you by the ActivityManager.getMemoryClass() method.

Here's an example code snippet and the method definition in the docs for reference.

    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    int memClassBytes = am.getMemoryClass() * 1024 * 1024;
    int cacheSize = memClassBytes / 8;
    mMemoryCache = new LruCache<String, Bitmap>(cacheSize)

http://developer.android.com/reference/android/app/ActivityManager.html#getMemoryClass%28%29

Gorham answered 4/4, 2013 at 3:21 Comment(1)
If i were a Football Commentator : Rich Strikes again , solid Goal , Dalvik has no chance to stop this Code , what a of this beautiful evening !Bornholm
A
0

You can also recycle bitmaps that pops out from lrucache

final Bitmap bmp = mLruCache.put(key, data);
if (bmp != null)
    bmp.recycle();
Ascending answered 4/10, 2013 at 15:14 Comment(0)
B
0

The Android example was wrong when dividing Runtime maxMemory by 1024 in the following line:

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

The unit of the maxMemory is Byte which is the same with the 'cacheSize' ('/ 8' just means it will use eighth of the available memory of the current Activity). Therefore, '/ 1024' will make the 'cacheSize' extremely small such that no bitmap can be actually 'cached' in 'mMemoryCache'.

The solution will be delete '/ 1024' in the above code.

Bridgettebridgewater answered 24/4, 2015 at 8:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.