Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trim and clear memory cache #35

Merged
merged 4 commits into from
Nov 7, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 36 additions & 4 deletions library/src/com/bumptech/glide/resize/cache/LruMemoryCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@

package com.bumptech.glide.resize.cache;

import android.graphics.Bitmap;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_MODERATE;

import android.graphics.Bitmap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
*/
Expand Down Expand Up @@ -47,9 +51,33 @@ public void setImageRemovedListener(ImageRemovedListener listener) {
this.imageRemovedListener = listener;
}

private void evict() {
LinkedHashMap.Entry<String, Bitmap> last;
while (currentSize > maxSize) {
@Override
public void clearMemory() {
final Iterator<Map.Entry<String,Bitmap>> iterator = cache.entrySet().iterator();
while (iterator.hasNext()) {
final Bitmap bitmap = iterator.next().getValue();
bitmap.recycle();
iterator.remove();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want to call recycle on the Bitmap here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also to answer your question, it is probably better to call the listener here when we remove each bitmap just to obey the interface. The practical affect of doing so is that the bitmaps will be dumped into the bitmap pool, which in turn will evict some bitmaps to make room.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I changed my mind. Call recycle on the bitmap and don't notify the listener. In the long run we probably don't want to call recycle and want to call the listener, but that will only work well if we've implemented a similar interface for the bitmap pool. Sorry for the confusion!

}
currentSize = 0;
}

@Override
public void trimMemory(int level) {
if (level >= TRIM_MEMORY_MODERATE) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will cause an exception on API < 14?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean because the onTrimMemory methods where added on 14? We are not calling any android methods here and the TRIM_MEMORY_* constants will be compiled into ints so they will run on older devices. You won't be able to compile the library on pre-14 though. Is that a problem?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes that's what I mean but I didn't realize the constants would be compiled, cool. It's ok if the library doesn't compile below the target, so this is fine.

// Nearing middle of list of cached background apps
// Evict our entire bitmap cache
clearMemory();
} else if (level >= TRIM_MEMORY_BACKGROUND) {
// Entering list of cached background apps
// Evict oldest half of our bitmap cache
trimToSize(currentSize / 2);
}
}

private void trimToSize(int size) {
Map.Entry<String, Bitmap> last;
while (currentSize > size) {
last = cache.entrySet().iterator().next();
final Bitmap toRemove = last.getValue();
currentSize -= getSize(toRemove);
Expand All @@ -60,4 +88,8 @@ private void evict() {
}
}
}

private void evict() {
trimToSize(maxSize);
}
}
12 changes: 12 additions & 0 deletions library/src/com/bumptech/glide/resize/cache/MemoryCache.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.bumptech.glide.resize.cache;

import android.content.ComponentCallbacks2;
import android.graphics.Bitmap;

/**
Expand Down Expand Up @@ -40,4 +41,15 @@ public interface ImageRemovedListener {
* @param listener The listener
*/
public void setImageRemovedListener(ImageRemovedListener listener);

/**
* Evict all items from the memory cache.
*/
public void clearMemory();

/**
* Trim the memory cache to the appropriate level. Typically called on the callback onTrimMemory.
* @param level This integer represents a trim level as specified in {@link ComponentCallbacks2}
*/
public void trimMemory(int level);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@ public Bitmap put(String key, Bitmap bitmap) {
public void setImageRemovedListener(ImageRemovedListener listener) {
this.listener = listener;
}

@Override
public void clearMemory() {}

@Override
public void trimMemory(int level) {}
}