11package com .bumptech .glide ;
22
33import android .app .Activity ;
4+ import android .app .Application ;
45import android .content .ComponentCallbacks2 ;
56import android .content .Context ;
67import android .content .res .Configuration ;
78import android .graphics .Bitmap ;
9+ import android .os .Bundle ;
810import android .os .MessageQueue .IdleHandler ;
911import android .util .Log ;
1012import android .view .View ;
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}
0 commit comments