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,8 @@ public class Glide implements ComponentCallbacks2 {
7779 private final RequestOptionsFactory defaultRequestOptionsFactory ;
7880 private MemoryCategory memoryCategory = MemoryCategory .NORMAL ;
7981
82+ private final MemoryCategory memoryCategoryInBackground ;
83+
8084 @ GuardedBy ("this" )
8185 @ Nullable
8286 private BitmapPreFiller bitmapPreFiller ;
@@ -205,7 +209,9 @@ public static void enableHardwareBitmaps() {
205209 public static void tearDown () {
206210 synchronized (Glide .class ) {
207211 if (glide != null ) {
208- glide .getContext ().getApplicationContext ().unregisterComponentCallbacks (glide );
212+ Application application = (Application ) glide .getContext ().getApplicationContext ();
213+ application .unregisterActivityLifecycleCallbacks (glide );
214+ application .unregisterComponentCallbacks (glide );
209215 glide .engine .shutdown ();
210216 }
211217 glide = null ;
@@ -224,7 +230,7 @@ private static void initializeGlide(
224230 @ NonNull Context context ,
225231 @ NonNull GlideBuilder builder ,
226232 @ Nullable GeneratedAppGlideModule annotationGeneratedModule ) {
227- Context applicationContext = context .getApplicationContext ();
233+ Application applicationContext = ( Application ) context .getApplicationContext ();
228234 List <GlideModule > manifestModules = Collections .emptyList ();
229235 if (annotationGeneratedModule == null || annotationGeneratedModule .isManifestParsingEnabled ()) {
230236 manifestModules = new ManifestParser (applicationContext ).parse ();
@@ -265,6 +271,7 @@ private static void initializeGlide(
265271 }
266272 Glide glide = builder .build (applicationContext , manifestModules , annotationGeneratedModule );
267273 applicationContext .registerComponentCallbacks (glide );
274+ applicationContext .registerActivityLifecycleCallbacks (glide );
268275 Glide .glide = glide ;
269276 }
270277
@@ -332,6 +339,11 @@ private static void throwIncorrectGlideModule(Exception e) {
332339 this .connectivityMonitorFactory = connectivityMonitorFactory ;
333340 this .defaultRequestOptionsFactory = defaultRequestOptionsFactory ;
334341
342+ GlideBuilder .MemoryCategoryInBackground memoryCategoryInBackground =
343+ experiments .get (GlideBuilder .MemoryCategoryInBackground .class );
344+ this .memoryCategoryInBackground = memoryCategoryInBackground != null ?
345+ memoryCategoryInBackground .value () : null ;
346+
335347 // This has a circular relationship with Glide and GlideContext in that it depends on both,
336348 // but it's created by Glide's constructor. In practice this shouldn't matter because the
337349 // supplier holding the registry should never be initialized before this constructor finishes.
@@ -446,6 +458,8 @@ public void clearMemory() {
446458 arrayPool .clearMemory ();
447459 }
448460
461+ private boolean inBackground = false ;
462+
449463 /**
450464 * Clears some memory with the exact amount depending on the given level.
451465 *
@@ -678,6 +692,12 @@ void unregisterRequestManager(RequestManager requestManager) {
678692 @ Override
679693 public void onTrimMemory (int level ) {
680694 trimMemory (level );
695+ // when level is TRIM_MEMORY_UI_HIDDEN or higher, it indicates that the app
696+ // is in the background, limit the memory usage by set memory category
697+ if (memoryCategoryInBackground != null && level >= TRIM_MEMORY_UI_HIDDEN ) {
698+ inBackground = true ;
699+ setMemoryCategory (memoryCategoryInBackground );
700+ }
681701 }
682702
683703 @ Override
@@ -697,4 +717,47 @@ public interface RequestOptionsFactory {
697717 @ NonNull
698718 RequestOptions build ();
699719 }
720+
721+ /**
722+ * Any activity that is started or resumed indicates that the app is no longer
723+ * in the background, and the memory category needs to be restored
724+ */
725+ @ Override
726+ public void onActivityStarted (Activity activity ) {
727+ if (memoryCategoryInBackground != null && inBackground ) {
728+ setMemoryCategory (MemoryCategory .NORMAL );
729+ }
730+ }
731+
732+ @ Override
733+ public void onActivityResumed (Activity activity ) {
734+ if (memoryCategoryInBackground != null && inBackground ) {
735+ setMemoryCategory (MemoryCategory .NORMAL );
736+ }
737+ }
738+
739+ @ Override
740+ public void onActivityCreated (Activity activity , Bundle savedIntsanceState ) {
741+ // Do nothing.
742+ }
743+
744+ @ Override
745+ public void onActivityDestroyed (Activity activity ) {
746+ // Do nothing.
747+ }
748+
749+ @ Override
750+ public void onActivityStopped (Activity activity ) {
751+ // Do nothing.
752+ }
753+
754+ @ Override
755+ public void onActivitySaveInstanceState (Activity activity , Bundle outState ) {
756+ // Do nothing.
757+ }
758+
759+ @ Override
760+ public void onActivityPaused (Activity activity ) {
761+ // Do nothing.
762+ }
700763}
0 commit comments