A fast and efficient open source media management and image loading framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy to use interface.
—
Error handling patterns, debugging utilities, and troubleshooting for image loading issues in Glide applications.
Event listeners for monitoring request success, failure, and lifecycle events.
/**
* Request event listener interface
*/
public interface RequestListener<R> {
/**
* Called when request fails
* @param e Exception details
* @param model Source model that failed
* @param target Target for the request
* @param isFirstResource true if this is the first resource requested
* @return true to prevent default error handling
*/
boolean onLoadFailed(@Nullable GlideException e, Object model, Target<R> target, boolean isFirstResource);
/**
* Called when resource is ready
* @param resource Loaded resource
* @param model Source model
* @param target Target for the request
* @param dataSource Where resource was loaded from
* @param isFirstResource true if this is the first resource loaded
* @return true to prevent default resource handling
*/
boolean onResourceReady(R resource, Object model, Target<R> target, DataSource dataSource, boolean isFirstResource);
}
/**
* Experimental request listener with additional callbacks
*/
public interface ExperimentalRequestListener<R> extends RequestListener<R> {
/**
* Called when request starts
* @param model Source model
* @param target Request target
* @return true to prevent default start handling
*/
boolean onLoadStarted(@Nullable Object model, Target<R> target);
/**
* Called when request is cleared
* @param model Source model
* @param target Request target
* @return true to prevent default clear handling
*/
boolean onLoadCleared(@Nullable Object model, Target<R> target);
}Usage Examples:
// Basic request listener
RequestListener<Drawable> listener = new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
Log.e("Glide", "Failed to load image: " + model, e);
// Return false to allow default error handling (show error drawable)
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
Log.d("Glide", "Image loaded from: " + dataSource.name());
// Return false to allow default resource handling (display image)
return false;
}
};
Glide.with(context)
.load(imageUrl)
.listener(listener)
.into(imageView);
// Multiple listeners
Glide.with(context)
.load(imageUrl)
.listener(analyticsListener)
.addListener(debugListener)
.addListener(performanceListener)
.into(imageView);Exception hierarchy and error information for troubleshooting failed requests.
/**
* Main exception class for Glide errors
*/
public final class GlideException extends Exception {
/**
* Get the root cause of the exception
* @return Root cause throwable
*/
@Nullable public Throwable getCause();
/**
* Get all root causes in the exception chain
* @return List of root cause throwables
*/
@NonNull public List<Throwable> getRootCauses();
/**
* Log all root causes with specified tag
* @param tag Log tag to use
*/
public void logRootCauses(@NonNull String tag);
/**
* Get detailed error message with causes
* @return Formatted error message
*/
@Override
public String getMessage();
/**
* Get the exception class that caused the failure
* @return Exception class
*/
@NonNull public Class<?> getOrigin();
/**
* Get data source that failed
* @return Data source enum
*/
@NonNull public DataSource getDataSource();
}Error Handling Examples:
Glide.with(context)
.load(imageUrl)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
if (e != null) {
// Log detailed error information
Log.e("ImageLoad", "Failed to load: " + model);
e.logRootCauses("ImageLoad");
// Check specific error types
List<Throwable> causes = e.getRootCauses();
for (Throwable cause : causes) {
if (cause instanceof UnknownHostException) {
showNetworkError();
} else if (cause instanceof FileNotFoundException) {
showFileNotFoundError();
} else if (cause instanceof OutOfMemoryError) {
showMemoryError();
}
}
}
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(imageView);Information about where resources were loaded from for debugging and analytics.
/**
* Data source enumeration
*/
public enum DataSource {
/** Loaded from local file system */
LOCAL,
/** Loaded from remote URL */
REMOTE,
/** Loaded from disk cache (original data) */
DATA_DISK_CACHE,
/** Loaded from disk cache (transformed resource) */
RESOURCE_DISK_CACHE,
/** Loaded from memory cache */
MEMORY_CACHE
}Data Source Usage:
RequestListener<Drawable> analyticsListener = new RequestListener<Drawable>() {
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
// Track performance metrics
switch (dataSource) {
case MEMORY_CACHE:
analytics.trackImageCacheHit("memory");
break;
case DATA_DISK_CACHE:
case RESOURCE_DISK_CACHE:
analytics.trackImageCacheHit("disk");
break;
case REMOTE:
analytics.trackImageNetworkLoad();
break;
case LOCAL:
analytics.trackImageLocalLoad();
break;
}
return false;
}
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
analytics.trackImageLoadError(model.toString(), e);
return false;
}
};Tools and utilities for debugging image loading issues.
/**
* Debugging and tracing utilities
*/
public final class GlideTrace {
/**
* Begin tracing section for performance analysis
* @param name Section name
*/
public static void beginSection(@NonNull String name);
/**
* End current tracing section
*/
public static void endSection();
/**
* Begin section with formatted name
* @param format Format string
* @param args Format arguments
*/
public static void beginSectionFormat(@NonNull String format, Object... args);
}
/**
* Logging utilities
*/
public final class LogLevel {
public static final int VERBOSE = 2;
public static final int DEBUG = 3;
public static final int INFO = 4;
public static final int WARN = 5;
public static final int ERROR = 6;
}Debugging Examples:
// Enable verbose logging in module
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setLogLevel(Log.VERBOSE)
.setLogRequestOrigins(true);
}
// Performance tracing
public class TracingRequestListener implements RequestListener<Drawable> {
@Override
public boolean onLoadStarted(@Nullable Object model, Target<Drawable> target) {
GlideTrace.beginSection("ImageLoad: " + model);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
GlideTrace.endSection();
return false;
}
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
GlideTrace.endSection();
return false;
}
}Typical error scenarios and their solutions.
/**
* Common error handling patterns
*/
public class ErrorHandlingPatterns {
/**
* Handle network connectivity issues
*/
public static void handleNetworkErrors(GlideException e, String fallbackUrl) {
List<Throwable> causes = e.getRootCauses();
for (Throwable cause : causes) {
if (cause instanceof UnknownHostException ||
cause instanceof ConnectException ||
cause instanceof SocketTimeoutException) {
// Retry with fallback or show offline indicator
loadFallbackImage(fallbackUrl);
break;
}
}
}
/**
* Handle memory pressure
*/
public static void handleMemoryErrors(Context context, GlideException e) {
for (Throwable cause : e.getRootCauses()) {
if (cause instanceof OutOfMemoryError) {
// Clear memory cache and retry
Glide.get(context).clearMemory();
// Reduce image quality for subsequent loads
RequestOptions options = new RequestOptions()
.format(DecodeFormat.PREFER_RGB_565)
.downsample(DownsampleStrategy.AT_MOST);
break;
}
}
}
/**
* Handle invalid URLs or missing resources
*/
public static boolean handleMissingResource(GlideException e, Object model) {
for (Throwable cause : e.getRootCauses()) {
if (cause instanceof FileNotFoundException ||
cause instanceof MalformedURLException) {
Log.w("Glide", "Invalid resource: " + model);
return true; // Resource is invalid
}
}
return false;
}
}Error Pattern Usage:
RequestListener<Drawable> robustListener = new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
if (e != null) {
// Handle network issues
if (isNetworkError(e)) {
ErrorHandlingPatterns.handleNetworkErrors(e, fallbackImageUrl);
return true; // Prevent default error drawable
}
// Handle memory issues
if (isMemoryError(e)) {
ErrorHandlingPatterns.handleMemoryErrors(context, e);
// Retry with lower quality
retryWithLowerQuality(model, target);
return true;
}
// Handle invalid resources
if (ErrorHandlingPatterns.handleMissingResource(e, model)) {
showPlaceholder(target);
return true;
}
}
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
};// Exception cause information
public static class Cause {
@NonNull private final Throwable exception;
@NonNull private final String description;
public Cause(@NonNull Throwable exception, @NonNull String description);
@NonNull public Throwable getException();
@NonNull public String getDescription();
}
// Request origin tracking
public static class RequestOrigin {
@NonNull private final String stackTrace;
@NonNull private final String threadName;
public RequestOrigin(@NonNull String stackTrace, @NonNull String threadName);
@NonNull public String getStackTrace();
@NonNull public String getThreadName();
}Install with Tessl CLI
npx tessl i tessl/maven-com-github-bumptech-glide--glide