Skip to content

Commit 0c1d3e8

Browse files
Eric Miaoericmiao
authored andcommitted
Limit the size of LruBitmapPool/MemoryCache when app is in background
When an app is moved to background, onTrimMemory() will be called, and LruBitmapPool/MemoryCache will be trimmed. However, the app could keep running and bitmaps will be retired to MemoryCache and LruBitmapPool. This change allows limit of the sizes of LruBitmapPool/MemoryCache (by MemoryCategory) when the app is in background, and restore the sizes to normal when it's moved out of background.
1 parent d52de59 commit 0c1d3e8

File tree

3 files changed

+90
-3
lines changed

3 files changed

+90
-3
lines changed

library/src/main/java/com/bumptech/glide/Glide.java

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.bumptech.glide;
22

33
import android.app.Activity;
4+
import android.app.Application;
45
import android.content.ComponentCallbacks2;
56
import android.content.Context;
67
import android.content.res.Configuration;
78
import android.graphics.Bitmap;
9+
import android.os.Bundle;
810
import android.os.MessageQueue.IdleHandler;
911
import android.util.Log;
1012
import android.view.View;
@@ -50,7 +52,7 @@
5052
* RequestBuilder} and maintaining an {@link Engine}, {@link BitmapPool}, {@link
5153
* com.bumptech.glide.load.engine.cache.DiskCache} and {@link MemoryCache}.
5254
*/
53-
public class Glide implements ComponentCallbacks2 {
55+
public class Glide implements ComponentCallbacks2, Application.ActivityLifecycleCallbacks {
5456
private static final String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";
5557
private static final String DESTROYED_ACTIVITY_WARNING =
5658
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
@@ -77,6 +79,9 @@ public class Glide implements ComponentCallbacks2 {
7779
private final RequestOptionsFactory defaultRequestOptionsFactory;
7880
private MemoryCategory memoryCategory = MemoryCategory.NORMAL;
7981

82+
private final MemoryCategory memoryCategoryInBackground;
83+
private boolean inBackground;
84+
8085
@GuardedBy("this")
8186
@Nullable
8287
private BitmapPreFiller bitmapPreFiller;
@@ -205,7 +210,9 @@ public static void enableHardwareBitmaps() {
205210
public static void tearDown() {
206211
synchronized (Glide.class) {
207212
if (glide != null) {
208-
glide.getContext().getApplicationContext().unregisterComponentCallbacks(glide);
213+
Application application = (Application) glide.getContext().getApplicationContext();
214+
application.unregisterActivityLifecycleCallbacks(glide);
215+
application.unregisterComponentCallbacks(glide);
209216
glide.engine.shutdown();
210217
}
211218
glide = null;
@@ -224,7 +231,7 @@ private static void initializeGlide(
224231
@NonNull Context context,
225232
@NonNull GlideBuilder builder,
226233
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
227-
Context applicationContext = context.getApplicationContext();
234+
Application applicationContext = (Application) context.getApplicationContext();
228235
List<GlideModule> manifestModules = Collections.emptyList();
229236
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
230237
manifestModules = new ManifestParser(applicationContext).parse();
@@ -265,6 +272,7 @@ private static void initializeGlide(
265272
}
266273
Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
267274
applicationContext.registerComponentCallbacks(glide);
275+
applicationContext.registerActivityLifecycleCallbacks(glide);
268276
Glide.glide = glide;
269277
}
270278

@@ -332,6 +340,11 @@ private static void throwIncorrectGlideModule(Exception e) {
332340
this.connectivityMonitorFactory = connectivityMonitorFactory;
333341
this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;
334342

343+
GlideBuilder.MemoryCategoryInBackground memoryCategoryInBackground =
344+
experiments.get(GlideBuilder.MemoryCategoryInBackground.class);
345+
this.memoryCategoryInBackground = memoryCategoryInBackground != null ?
346+
memoryCategoryInBackground.value() : null;
347+
335348
// This has a circular relationship with Glide and GlideContext in that it depends on both,
336349
// but it's created by Glide's constructor. In practice this shouldn't matter because the
337350
// supplier holding the registry should never be initialized before this constructor finishes.
@@ -678,6 +691,12 @@ void unregisterRequestManager(RequestManager requestManager) {
678691
@Override
679692
public void onTrimMemory(int level) {
680693
trimMemory(level);
694+
// when level is TRIM_MEMORY_UI_HIDDEN or higher, it indicates that the app
695+
// is in the background, limit the memory usage by set memory category
696+
if (memoryCategoryInBackground != null && level >= TRIM_MEMORY_UI_HIDDEN) {
697+
inBackground = true;
698+
setMemoryCategory(memoryCategoryInBackground);
699+
}
681700
}
682701

683702
@Override
@@ -697,4 +716,47 @@ public interface RequestOptionsFactory {
697716
@NonNull
698717
RequestOptions build();
699718
}
719+
720+
/**
721+
* Any activity started or resumed indicates that the app is no longer
722+
* in the background, and the memory category needs to be restored.
723+
*/
724+
@Override
725+
public void onActivityStarted(Activity activity) {
726+
if (memoryCategoryInBackground != null && inBackground) {
727+
setMemoryCategory(MemoryCategory.NORMAL);
728+
}
729+
}
730+
731+
@Override
732+
public void onActivityResumed(Activity activity) {
733+
if (memoryCategoryInBackground != null && inBackground) {
734+
setMemoryCategory(MemoryCategory.NORMAL);
735+
}
736+
}
737+
738+
@Override
739+
public void onActivityCreated(Activity activity, Bundle savedIntsanceState) {
740+
// Do nothing.
741+
}
742+
743+
@Override
744+
public void onActivityDestroyed(Activity activity) {
745+
// Do nothing.
746+
}
747+
748+
@Override
749+
public void onActivityStopped(Activity activity) {
750+
// Do nothing.
751+
}
752+
753+
@Override
754+
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
755+
// Do nothing.
756+
}
757+
758+
@Override
759+
public void onActivityPaused(Activity activity) {
760+
// Do nothing.
761+
}
700762
}

library/src/main/java/com/bumptech/glide/GlideBuilder.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,15 @@ public GlideBuilder setDisableHardwareBitmapsOnO(boolean disableHardwareBitmapsO
539539
return this;
540540
}
541541

542+
/**
543+
* This method sets the memory category when the app is in the background.
544+
*/
545+
public GlideBuilder setMemoryCategoryInBackground(@Nullable MemoryCategory category) {
546+
glideExperimentsBuilder.update(new MemoryCategoryInBackground(category),
547+
category != null ? true : false);
548+
return this;
549+
}
550+
542551
void setRequestManagerFactory(@Nullable RequestManagerFactory factory) {
543552
this.requestManagerFactory = factory;
544553
}
@@ -653,4 +662,16 @@ public static final class OverrideGlideThreadPriority implements Experiment {}
653662

654663
/** See {@link #setUseMediaStoreOpenFileApisIfPossible(boolean)}. */
655664
public static final class UseMediaStoreOpenFileApisIfPossible implements Experiment {}
665+
666+
public static final class MemoryCategoryInBackground implements Experiment {
667+
private final MemoryCategory category;
668+
669+
public MemoryCategoryInBackground(MemoryCategory category) {
670+
this.category = category;
671+
}
672+
673+
public MemoryCategory value() {
674+
return this.category;
675+
}
676+
}
656677
}

library/src/main/java/com/bumptech/glide/MemoryCategory.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
/** An enum for dynamically modifying the amount of memory Glide is able to use. */
44
public enum MemoryCategory {
5+
/**
6+
* Tells Glide's memory cache and bitmap pool to use no memory.
7+
*/
8+
ZERO(0.0f),
59
/**
610
* Tells Glide's memory cache and bitmap pool to use at most half of their initial maximum size.
711
*/

0 commit comments

Comments
 (0)