Configuration

Róbert Papp edited this page Jul 12, 2016 · 12 revisions

Lazy Configuration

Starting in Glide 3.5, you can use the GlideModule interface to lazily configure Glide and register components like ModelLoaders automatically when the first Glide request is made.

Creating a GlideModule

To use and register a GlideModule, first implement the interface with your configuration and components:

package com.mypackage;

public class MyGlideModule implements GlideModule {
    @Override public void applyOptions(Context context, GlideBuilder builder) {
        // Apply options to the builder here.
    }

    @Override public void registerComponents(Context context, Glide glide) {
        // register ModelLoaders here.
    }
}

You can implement as many GlideModules as you like, although each one must be added to ProGuard/DexGuard exceptions and each one must have its own meta-data tag in the manifest. See below for more details on these.

Keeping a GlideModule

Then add your implementation class to your proguard.cfg/proguard.pro file to allow your module to be instantiated via reflection. This will make sure ProGuard and DexGuard is not marking it as unused. The performance overhead of reflection is minimal, because each module is instantiated a single time, when the first request with Glide is made.

-keepnames class com.mypackage.MyGlideModule
# or more generally:
#-keep public class * implements com.bumptech.glide.module.GlideModule

# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule

Registering a GlideModule

Finally add a meta-data tag to your AndroidManifest.xml file so Glide can find your module:

<manifest ...>
    <!-- ... permissions -->
    <application ...>
        <meta-data
            android:name="com.mypackage.MyGlideModule"
            android:value="GlideModule" />
        <!-- ... activities and other components -->
    </application>
</manifest>

Library projects

Library projects may define one or more GlideModules. If a library project adds a module to its manifest, applications built using Gradle (or any system with a manifest merger) that depend on the library project will automatically pick up the library's module. If no manifest merger is available, the library module will have to be manually listed in the application's manifest.

Conflicting GlideModules

Although Glide allows multiple GlideModule to be registered per application, it doesn't call them in any particular order. As a result, users ares responsible for avoiding conflicts between registrations if their application defines more than one or depends on multiple libraries that define GlideModules.

If a conflict is unavoidable, applications should default to defining their own module that manually resolves the conflict and provides all dependencies required by the library modules. Gradle users, or any other user using a manifest merger, can exclude conflicting modules by adding a tag to their AndroidManifest.xml to exclude the corresponding meta-data tags:

<meta-data android:name=”com.mypackage.MyGlideModule” tools:node=”remove” />

Global Configuration

Glide allows you to configure a number of different global options that apply to all requests. To do so you use the GlideBuilder provided to you in GlideModule#applyOptions. The code examples in this section will refer to it as builder.

Disk Cache

You can use the GlideBuilder's setDiskCache() method to set the location and/or maximum size of the disk cache. You can also disable the cache entirely using DiskCacheAdapter or replace it with your own implementation of the DiskCache interface. Disk caches are built on background threads to avoid strict mode violations using the DiskCache.Factory interface.

By default Glide uses the InternalCacheDiskCacheFactory class to build disk caches. The internal cache factory places the disk cache in your application's internal cache directory and sets a maximum size of 250MB. Using the cache directory rather than the external SD card means no other applications will be able to access the images you download. See Android's Storage Options doc for more details.

Size

You can set the size of the disk cache using the InternalCacheDiskCacheFactory:

builder.setDiskCache(
  new InternalCacheDiskCacheFactory(context, yourSizeInBytes));

Location

Setting the location of the disk cache is also possible.

You can use the built in InternalCacheDiskCacheFactory to place your cache in your applications private internal cache directory:

builder.setDiskCache(
  new InternalCacheDiskCacheFactory(context, cacheDirectoryName, yourSizeInBytes));

You can also use the built in ExternalCacheDiskCacheFactory to place your cache in your applications public cache directory on the sd card:

builder.setDiskCache(
  new ExternalCacheDiskCacheFactory(context, cacheDirectoryName, yourSizeInBytes));

If you'd like to use some other custom location, you can leverage the DiskLruCacheFactory class's constructors:

// If you can figure out the folder without I/O:
// Calling Context and Environment class methods usually do I/O.
builder.setDiskCache(
  new DiskLruCacheFactory(getMyCacheLocationWithoutIO(), yourSizeInBytes));

// In case you want to specify a cache folder ("glide"):
builder.setDiskCache(
  new DiskLruCacheFactory(getMyCacheLocationWithoutIO(), "glide", yourSizeInBytes));

// In case you need to query the file system while determining the folder:
builder.setDiskCache(new DiskLruCacheFactory(new CacheDirectoryGetter() {
    @Override public File getCacheDirectory() {
        return getMyCacheLocationBlockingIO();
    }
}), yourSizeInBytes);

Note: Please remember, hardcoding any value is never a good idea, especially directory paths since Android 4.2, which enables multiple users on a single device.

If you want full control of your cache creation you can also implement the DiskCache.Factory interface yourself, and use the DiskLruCacheWrapper to create a new cache in your desired location:

builder.setDiskCache(new DiskCache.Factory() {
    @Override public DiskCache build() {
        File cacheLocation = getMyCacheLocationBlockingIO();
        cacheLocation.mkdirs();
        return DiskLruCacheWrapper.get(cacheLocation, yourSizeInBytes);
    }
});

Memory caches and pools

The GlideBuilder class allows you to set the size and implementation of Glide's MemoryCache and BitmapPool.

Size

Default sizes are determined by the MemorySizeCalculator class. The MemorySizeCalculator class takes into account the screen size available memory of a given device to come up with reasonable default sizes. You can construct your own instance if you want to adjust Glide's defaults:

MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();

If you want to dynamically adjust Glide's memory footprint during certain phases of your application, you can do so by picking a MemoryCategory and passing it to Glide using setMemoryCategory():

Glide.get(context).setMemoryCategory(MemoryCategory.HIGH);

Memory Cache

Glide's memory cache is used to hold resources in memory so that they are instantly available without having to perform I/O.

You can use GlideBuilder's setMemoryCache() method to set the size and/or implementation you wish to use for your memory cache. The LruResourceCache class is Glide's default implementation. You can set a custom maximum in memory byte size by passing in the size you want to the LruResourceCache constructor:

builder.setMemoryCache(new LruResourceCache(yourSizeInBytes));

Bitmap Pool

Glide's bitmap pool is used to allow Bitmaps of a variety of different sizes to be re-used which can substantially reduce jank inducing garbage collections caused by pixel array allocations while images are being decoded.

You can use GlideBuilder's setBitmapPool() method to set the size and/or implementation of the bitmap pool. The LruBitmapPool class is Glide's default implementation. The LruBitmapPool class uses an LRU algorithm to retain the most recently used sizes of Bitmaps. You can set a custom maximum in memory byte size by passing the size you want to the LruBitmapPool constructor:

builder.setBitmapPool(new LruBitmapPool(sizeInBytes));

Bitmap Format

The GlideBuilder class also allows you to set a global default for the preferred Bitmap configuration for your application.

By default Glide prefers RGB_565 because it requires only two bytes per pixel (16 bit) and therefore has half the memory footprint of the higher quality and system default ARGB_8888. RGB_565 however can have issues with banding in certain images and also does not support transparency.

If banding is a problem in your application and/or you want the highest possible image quality, you can use GlideBuilder's setDecodeFormat method to set DecodeFormat.ALWAYS_ARGB_8888 as Glide's preferred Bitmap configuration:

builder.setDecodeFormat(DecodeFormat.ALWAYS_ARGB_8888);