Skip to content
Open
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
68 changes: 65 additions & 3 deletions library/src/main/java/com/bumptech/glide/Glide.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.bumptech.glide;

import android.app.Activity;
import android.app.Application;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.MessageQueue.IdleHandler;
import android.util.Log;
import android.view.View;
Expand Down Expand Up @@ -50,7 +52,7 @@
* RequestBuilder} and maintaining an {@link Engine}, {@link BitmapPool}, {@link
* com.bumptech.glide.load.engine.cache.DiskCache} and {@link MemoryCache}.
*/
public class Glide implements ComponentCallbacks2 {
public class Glide implements ComponentCallbacks2, Application.ActivityLifecycleCallbacks {
private static final String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";
private static final String DESTROYED_ACTIVITY_WARNING =
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
Expand All @@ -77,6 +79,9 @@ public class Glide implements ComponentCallbacks2 {
private final RequestOptionsFactory defaultRequestOptionsFactory;
private MemoryCategory memoryCategory = MemoryCategory.NORMAL;

private final MemoryCategory memoryCategoryInBackground;
private boolean inBackground;

@GuardedBy("this")
@Nullable
private BitmapPreFiller bitmapPreFiller;
Expand Down Expand Up @@ -205,7 +210,9 @@ public static void enableHardwareBitmaps() {
public static void tearDown() {
synchronized (Glide.class) {
if (glide != null) {
glide.getContext().getApplicationContext().unregisterComponentCallbacks(glide);
Application application = (Application) glide.getContext().getApplicationContext();
application.unregisterActivityLifecycleCallbacks(glide);
application.unregisterComponentCallbacks(glide);
glide.engine.shutdown();
}
glide = null;
Expand All @@ -224,7 +231,7 @@ private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
Context applicationContext = context.getApplicationContext();
Application applicationContext = (Application) context.getApplicationContext();
List<GlideModule> manifestModules = Collections.emptyList();
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
Expand Down Expand Up @@ -265,6 +272,7 @@ private static void initializeGlide(
}
Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
applicationContext.registerComponentCallbacks(glide);
applicationContext.registerActivityLifecycleCallbacks(glide);
Glide.glide = glide;
}

Expand Down Expand Up @@ -332,6 +340,11 @@ private static void throwIncorrectGlideModule(Exception e) {
this.connectivityMonitorFactory = connectivityMonitorFactory;
this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;

GlideBuilder.MemoryCategoryInBackground memoryCategoryInBackground =
experiments.get(GlideBuilder.MemoryCategoryInBackground.class);
this.memoryCategoryInBackground = memoryCategoryInBackground != null ?
memoryCategoryInBackground.value() : null;

// This has a circular relationship with Glide and GlideContext in that it depends on both,
// but it's created by Glide's constructor. In practice this shouldn't matter because the
// supplier holding the registry should never be initialized before this constructor finishes.
Expand Down Expand Up @@ -678,6 +691,12 @@ void unregisterRequestManager(RequestManager requestManager) {
@Override
public void onTrimMemory(int level) {
trimMemory(level);
// when level is TRIM_MEMORY_UI_HIDDEN or higher, it indicates that the app
// is in the background, limit the memory usage by set memory category
if (memoryCategoryInBackground != null && level >= TRIM_MEMORY_UI_HIDDEN) {
inBackground = true;
setMemoryCategory(memoryCategoryInBackground);
}
}

@Override
Expand All @@ -697,4 +716,47 @@ public interface RequestOptionsFactory {
@NonNull
RequestOptions build();
}

/**
* Any activity started or resumed indicates that the app is no longer
* in the background, and the memory category needs to be restored.
*/
@Override
public void onActivityStarted(Activity activity) {
if (memoryCategoryInBackground != null && inBackground) {
setMemoryCategory(MemoryCategory.NORMAL);
}
}

@Override
public void onActivityResumed(Activity activity) {
if (memoryCategoryInBackground != null && inBackground) {
setMemoryCategory(MemoryCategory.NORMAL);
}
}

@Override
public void onActivityCreated(Activity activity, Bundle savedIntsanceState) {
// Do nothing.
}

@Override
public void onActivityDestroyed(Activity activity) {
// Do nothing.
}

@Override
public void onActivityStopped(Activity activity) {
// Do nothing.
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
// Do nothing.
}

@Override
public void onActivityPaused(Activity activity) {
// Do nothing.
}
}
21 changes: 21 additions & 0 deletions library/src/main/java/com/bumptech/glide/GlideBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,15 @@ public GlideBuilder setDisableHardwareBitmapsOnO(boolean disableHardwareBitmapsO
return this;
}

/**
* This method sets the memory category when the app is in the background.
*/
public GlideBuilder setMemoryCategoryInBackground(@Nullable MemoryCategory category) {
glideExperimentsBuilder.update(new MemoryCategoryInBackground(category),
category != null ? true : false);
return this;
}

void setRequestManagerFactory(@Nullable RequestManagerFactory factory) {
this.requestManagerFactory = factory;
}
Expand Down Expand Up @@ -653,4 +662,16 @@ public static final class OverrideGlideThreadPriority implements Experiment {}

/** See {@link #setUseMediaStoreOpenFileApisIfPossible(boolean)}. */
public static final class UseMediaStoreOpenFileApisIfPossible implements Experiment {}

public static final class MemoryCategoryInBackground implements Experiment {
private final MemoryCategory category;

public MemoryCategoryInBackground(MemoryCategory category) {
this.category = category;
}

public MemoryCategory value() {
return this.category;
}
}
}
4 changes: 4 additions & 0 deletions library/src/main/java/com/bumptech/glide/MemoryCategory.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

/** An enum for dynamically modifying the amount of memory Glide is able to use. */
public enum MemoryCategory {
/**
* Tells Glide's memory cache and bitmap pool to use no memory.
*/
ZERO(0.0f),
/**
* Tells Glide's memory cache and bitmap pool to use at most half of their initial maximum size.
*/
Expand Down