From 4587c1550dafd716480a0587990518092e74fb52 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 10 Jun 2020 23:13:07 -0700 Subject: [PATCH] Cache WeakReferences to our box art bitmaps after LRU evictions --- .../grid/assets/MemoryAssetLoader.java | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/limelight/grid/assets/MemoryAssetLoader.java b/app/src/main/java/com/limelight/grid/assets/MemoryAssetLoader.java index 8763c5a1..6728798d 100644 --- a/app/src/main/java/com/limelight/grid/assets/MemoryAssetLoader.java +++ b/app/src/main/java/com/limelight/grid/assets/MemoryAssetLoader.java @@ -5,6 +5,9 @@ import android.util.LruCache; import com.limelight.LimeLog; +import java.lang.ref.WeakReference; +import java.util.HashMap; + public class MemoryAssetLoader { private static final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); private static final LruCache memoryCache = new LruCache(maxMemory / 16) { @@ -13,18 +16,51 @@ public class MemoryAssetLoader { // Sizeof returns kilobytes return bitmap.getByteCount() / 1024; } + + @Override + protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) { + super.entryRemoved(evicted, key, oldValue, newValue); + + if (evicted) { + // Keep a weak reference around to the bitmap as long as we can + evictionCache.put(key, new WeakReference<>(oldValue)); + } + } }; + private static final HashMap> evictionCache = new HashMap<>(); private static String constructKey(CachedAppAssetLoader.LoaderTuple tuple) { return tuple.computer.uuid+"-"+tuple.app.getAppId(); } public Bitmap loadBitmapFromCache(CachedAppAssetLoader.LoaderTuple tuple) { - Bitmap bmp = memoryCache.get(constructKey(tuple)); + final String key = constructKey(tuple); + + Bitmap bmp = memoryCache.get(key); if (bmp != null) { - LimeLog.info("Memory cache hit for tuple: "+tuple); + LimeLog.info("LRU cache hit for tuple: "+tuple); + return bmp; } - return bmp; + + WeakReference bmpRef = evictionCache.get(key); + if (bmpRef != null) { + bmp = bmpRef.get(); + if (bmp != null) { + LimeLog.info("Eviction cache hit for tuple: "+tuple); + + // Put this entry back into the LRU cache + evictionCache.remove(key); + memoryCache.put(key, bmp); + + return bmp; + } + else { + // The data is gone, so remove the dangling WeakReference now + evictionCache.remove(key); + } + } + + return null; } public void populateCache(CachedAppAssetLoader.LoaderTuple tuple, Bitmap bitmap) { @@ -32,6 +68,8 @@ public class MemoryAssetLoader { } public void clearCache() { + // We must evict first because that will push all items into the eviction cache memoryCache.evictAll(); + evictionCache.clear(); } }