glide源码解析之GlideModule

本文详细解析了Glide全局配置的实现原理,介绍了GlideModule接口及其应用方式,并深入探讨了GlideBuilder类中用于设置缓存策略、解码格式等关键属性的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GlideModule是对glide全局配置相关的类,这里介绍相关配置的源码解析
一般的用法是这样
public class GlideConfiguration implements GlideModule {

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
        MemorySizeCalculator calculator = new MemorySizeCalculator(context);
        int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
        int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
        int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
        int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
        builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize)); //设置图片缓存策略
        builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize));
        int cacheSize100MegaBytes = 104857600;  //100M
        String downloadDirectoryPath = Environment.getExternalStorageDirectory().getPath();
        builder.setDiskCache(new DiskLruCacheFactory(downloadDirectoryPath, "cache/", cacheSize100MegaBytes));
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        glide.register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
    }
}
然后再manifest文件中加入这个配置
        <meta-data
            android:name=".GlideConfiguration"
            android:value="GlideModule"/>

先看看GlideMoudle接口源码
package com.bumptech.glide.module ;

import android.content.Context ;

import com.bumptech.glide.Glide ;
import com.bumptech.glide.GlideBuilder ;

/**
 * An interface allowing lazy configuration of Glide including setting options using
 * { @link  com.bumptech.glide.GlideBuilder} and registering
 * { @link  com.bumptech.glide.load.model.ModelLoader ModelLoaders}.
 *
 *  <p>
  *     To use this interface:
 *      <ol>
  *          <li>
  *             Implement the GlideModule interface in a class with public visibility, calling
 *             { @link  com.bumptech.glide.Glide#register(Class, Class, com.bumptech.glide.load.model.ModelLoaderFactory)}
 *             for each { @link  com.bumptech.glide.load.model.ModelLoader} you'd like to register:
 *              <pre>
  *                  <code>
  *                      public class FlickrGlideModule implements GlideModule {
 *                          { @literal  @}Override
 *                          public void applyOptions(Context context, GlideBuilder builder) {
 *                              buidler.setDecodeFormat(DecodeFormat.ALWAYS_ARGB_8888);
 *                          }
 *
 *                          { @literal  @}Override
 *                          public void registerComponents(Context context, Glide glide) {
 *                              glide.register(Model.class, Data.class, new MyModelLoader());
 *                          }
 *                      }
 *                  </code>
  *              </pre>
  *          </li>
  *          <li>
  *              Add your implementation to your list of keeps in your proguard.cfg file:
 *              <pre>
  *                  { @code
  *                      -keepnames class * com.bumptech.glide.samples.flickr.FlickrGlideModule
 *                  }
 *              </pre>
  *          </li>
  *          <li>
  *             Add a metadata tag to your AndroidManifest.xml with your GlideModule implementation's fully qualified
 *             classname as the key, and { @code  GlideModule} as the value:
 *              <pre>
  *                 { @code
  *                      <meta-data
  *                          android:name="com.bumptech.glide.samples.flickr.FlickrGlideModule"
 *                          android:value="GlideModule" />
 *                 }
 *              </pre>
  *          </li>
  *      </ol>
  </p>
  *
 *  <p>
  *     All implementations must be publicly visible and contain only an empty constructor so they can be instantiated
 *     via reflection when Glide is lazily initialized.
 *  </p>
  *
 *  <p>
  *     There is no defined order in which modules are called, so projects should be careful to avoid applying
 *     conflicting settings in different modules. If an application depends on libraries that have conflicting
 *     modules, the application should consider avoiding the library modules and instead providing their required
 *     dependencies in a single application module.
 *  </p>
  */
public interface  GlideModule {

    /**
     * Lazily apply options to a { @link  com.bumptech.glide.GlideBuilder} immediately before the Glide singleton is
     * created.
     *
     *  <p>
      *     This method will be called once and only once per implementation.
     *  </p>
      *
     *  @param  context  An Application { @link  android.content.Context}.
     *  @param  builder  The { @link  com.bumptech.glide.GlideBuilder} that will be used to create Glide.
     */
    void  applyOptions(Context context GlideBuilder builder) ;

    /**
     * Lazily register components immediately after the Glide singleton is created but before any requests can be
     * started.
     *
     *  <p>
      *     This method will be called once and only once per implementation.
     *  </p>
      *
     *  @param  context  An Application { @link  android.content.Context}.
     *  @param  glide  The newly created Glide singleton.
     */
    void  registerComponents(Context context Glide glide) ;
}

上面一堆注释介绍是怎么用的,最终就是两个方法需要实现。
一个是设置属性,一个是注册组件。
看设置属性的,先看参数GlideBuilder
/**
 * A builder class for setting default structural classes for Glide to use.
 */
public class GlideBuilder {

里边含有一些方法
/**
 * Sets the { @link  com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} implementation to use to store and
 * retrieve reused { @link  android.graphics.Bitmap}s.
 *
 *  @param  bitmapPool  The pool to use.
 *  @return  This builder.
 */
public GlideBuilder  setBitmapPool(BitmapPool bitmapPool) {
    this. bitmapPool = bitmapPool ;
    return this;
}

这个是设置bitmap池的,是在内存中存储以bitmap形式,大家应该都知道这个是占用内存比较大的,但是速度是最快的。

/**
 * Sets the { @link  com.bumptech.glide.load.engine.cache.MemoryCache} implementation to store
 * { @link  com.bumptech.glide.load.engine.Resource}s that are not currently in use.
 *
 *  @param  memoryCache  The cache to use.
 *  @return  This builder.
 */
public GlideBuilder  setMemoryCache(MemoryCache memoryCache) {
    this. memoryCache = memoryCache ;
    return this;
}

这个是内存缓存的是以文件或者流的方式存在内存中的,没有上面那个处理速度快,但是比在磁盘读写和加载网络要快很多的。
上面两种都是在内存中存储的,在默认实现中,他们两种总共占内存的0.33-0.4的空间,如果在低内存下还有其他的处理,他们俩各占这部分内存的一半。

/**
 * Sets the { @link  com.bumptech.glide.load.engine.cache.DiskCache.Factory} implementation to use to construct
 * the { @link  com.bumptech.glide.load.engine.cache.DiskCache} to use to store
 * { @link  com.bumptech.glide.load.engine.Resource} data on disk.
 *
 *  @param  diskCacheFactory  The disk cche factory to use.
 *  @return  This builder.
 */
public GlideBuilder  setDiskCache(DiskCache.Factory diskCacheFactory) {
    this. diskCacheFactory = diskCacheFactory ;
    return this;
}
讲网络中下载的数据存储到磁盘中。不用重复下载,这个也可以自己去实现,如何存储以及存储的方式算法。

Glide是支持扩展性比较高的,基于接口去配置,可以实现对其灵活的扩展,上面是有一些默认实现的,如果需要更高级的用法,可以自己实现缓存策略,和硬盘存储策略。


/**
 * Sets the { @link  com.bumptech.glide.load.DecodeFormat} that will be the default format for all the default
 * decoders that can change the { @link  android.graphics.Bitmap.Config} of the { @link  android.graphics.Bitmap}s they
 * decode.
 *
 *  <p>
  *     Decode format is always a suggestion, not a requirement. See { @link  com.bumptech.glide.load.DecodeFormat} for
 *     more details.
 *  </p>
  *
 *  <p>
  *     If you instantiate and use a custom decoder, it will use
 *     { @link  com.bumptech.glide.load.DecodeFormat#DEFAULT} as its default.
 *  </p>
  *
 *  <p>
  *     Calls to this method are ignored on KitKat and Lollipop. See #301.
 *  </p>
  *
 *  @param  decodeFormat  The format to use.
 *  @return  This builder.
 */
public GlideBuilder  setDecodeFormat(DecodeFormat decodeFormat) {
    this. decodeFormat = decodeFormat ;
    return this;
}

设置全局的bitmap解码格式
解码格式源码在这里
package com.bumptech.glide.load ;

/**
 * Options for setting the value of { @link  android.graphics.Bitmap#getConfig()} for { @link  android.graphics.Bitmap}s
 * returned by a { @link  com.bumptech.glide.load.resource.bitmap.BitmapDecoder}.
 *
 *  <p>
  *     Note - In some cases it may not be possible to obey the requested setting, not all
 *     { @link  com.bumptech.glide.load.resource.bitmap.BitmapDecoder}s support setting formats and certain images may
 *     not be able to be loaded as certain configurations. Therefore this class represents a preference rather than a
 *     requirement.
 *  </p>
  */
public enum DecodeFormat {
    /**
     * All bitmaps returned by the { @link  com.bumptech.glide.load.resource.bitmap.BitmapDecoder} should return
     * { @link  android.graphics.Bitmap.Config#ARGB_8888} for { @link  android.graphics.Bitmap#getConfig()}.
     *
     *  @deprecated  Use the equivalent but less misleadingly named { @link  #PREFER_ARGB_8888}. Scheduled to be removed
     * in Glide 4.0
     */
    @Deprecated
    ALWAYS_ARGB_8888 ,

    /**
     * Bitmaps decoded from most image formats (other than GIFs with hidden configs), will be decoded with the
     * ARGB_8888 config.
     *
     *  <p>
      *     { @link  android.graphics.BitmapFactory} does not allow us to guarantee that all returned Bitmaps will
     *     be of a requested config without resorting to expensive copying. As a result, this is a preference only.
     *     Most GIFs, for example, will still produce { @link  android.graphics.Bitmap}s with null
     *     { @link  android.graphics.Bitmap.Config}s.
     *  </p>
      */
    PREFER_ARGB_8888 ,

    /**
     * Bitmaps decoded from image formats that support and/or use alpha (some types of PNGs, GIFs etc) should
     * return { @link  android.graphics.Bitmap.Config#ARGB_8888} for { @link  android.graphics.Bitmap#getConfig()}. Bitmaps
     * decoded from formats that don't support or use alpha should return
     * { @link  android.graphics.Bitmap.Config#RGB_565} for { @link  android.graphics.Bitmap#getConfig()}.
     *
     */
    PREFER_RGB_565 ;

    /** The default value for DecodeFormat. */
    public static final DecodeFormat  DEFAULT PREFER_RGB_565 ;
}
这里默认是用Bitmap.option中国的565格式,我们也可以设置成888的格式,如下这样:
builder.setDecodeFormat(DecodeFormat. PREFER_ARGB_8888) ;

在GlideBuilder中的默认设置在此:
Glide  createGlide() {
    if ( sourceService ==  null) {
        final int cores = Math. max( 1 Runtime. getRuntime().availableProcessors()) ;
        sourceService new FifoPriorityThreadPoolExecutor(cores) ;
    }
    if ( diskCacheService ==  null) {
        diskCacheService new FifoPriorityThreadPoolExecutor( 1) ;
    }

    MemorySizeCalculator calculator =  new MemorySizeCalculator( context) ;
    if ( bitmapPool ==  null) {
        if (Build.VERSION. SDK_INT >= Build.VERSION_CODES. HONEYCOMB) {
            int size = calculator.getBitmapPoolSize() ;
            bitmapPool new LruBitmapPool(size) ;
       else {
            bitmapPool new BitmapPoolAdapter() ;
        }
    }

    if ( memoryCache ==  null) {
        memoryCache new LruResourceCache(calculator.getMemoryCacheSize()) ;
    }

    if ( diskCacheFactory ==  null) {
        diskCacheFactory new InternalCacheDiskCacheFactory( context) ;
    }

    if ( engine ==  null) {
        engine new Engine( memoryCache diskCacheFactory diskCacheService sourceService) ;
    }

    if ( decodeFormat ==  null) {
        decodeFormat = DecodeFormat. DEFAULT ;
    }

    return new  Glide( engine memoryCache bitmapPool context decodeFormat) ;
}

下面是类的成员变量
private final Context  context ;

private Engine  engine ;
private BitmapPool  bitmapPool ;
private MemoryCache  memoryCache ;
private ExecutorService  sourceService ;
private ExecutorService  diskCacheService ;
private DecodeFormat  decodeFormat ;
private DiskCache.Factory  diskCacheFactory ;

也就是除了context以外都是可以设置的
sourceService是从服务器来去图片资源的时候的处理策略
diskCacheService是从磁盘缓存是的策略
这两个默认的都是带有优先级的先进先出方式
用的是这个
public class FifoPriorityThreadPoolExecutor  extends ThreadPoolExecutor {

下面是bitmapPool处理方式
MemorySizeCalculator calculator =  new MemorySizeCalculator( context) ;
if ( bitmapPool ==  null) {
    if (Build.VERSION. SDK_INT >= Build.VERSION_CODES. HONEYCOMB) {
        int size = calculator.getBitmapPoolSize() ;
        bitmapPool new LruBitmapPool(size) ;
   else {
        bitmapPool new BitmapPoolAdapter() ;
    }
}

默认是根据SDK的版本处理不同的方式 Build.VERSION_CODES. HONEYCOMB = 11
MemorySizeCalculator 这个类是池大小计算的类,有感兴趣的可以读下,看看怎么计算的。
实现大概就是图片缓存占用整个APP内存的0.33-0.4的,其中的一半是给BitmapPool用的,另一半是给cache用的
这个bitmapPool要是自己实现要实现BitmapPool接口就可以了。
/**
 * An interface for a pool that allows users to reuse { @link  android.graphics.Bitmap} objects.
 */
public interface BitmapPool {

那个小于sdk11版本的默认是实现,就是什么都没有实现,下面是源码
/**
 * An { @link  com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool BitmapPool} implementation that rejects all
 * { @link  android.graphics.Bitmap Bitmap}s added to it and always returns { @code  null} from get.
 */
public class BitmapPoolAdapter  implements BitmapPool {
    @Override
    public int  getMaxSize() {
        return  0 ;
    }

    @Override
    public void  setSizeMultiplier( float sizeMultiplier) {
        // Do nothing.
    }

    @Override
    public boolean  put(Bitmap bitmap) {
        return false;
    }

    @Override
    public Bitmap  get( int width , int height Bitmap.Config config) {
        return null;
    }

    @Override
    public Bitmap  getDirty( int width , int height Bitmap.Config config) {
        return null;
    }

    @Override
    public void  clearMemory() {
        // Do nothing.
    }

    @Override
    public void  trimMemory( int level) {
        // Do nothing.
    }

然后看下LRU算法实现的bitmapPool。
/**
 * Constructor for LruBitmapPool.
 *
 *  @param  maxSize  The initial maximum size of the pool in bytes.
 */
public LruBitmapPool( int maxSize) {
    this(maxSize getDefaultStrategy() getDefaultAllowedConfigs()) ;
}

第一个是缓存池大小单位bytes
第二个是默认的缓存策略,
第三个是允许的配置,如ARGB565、ARGB888等
然后第二个缓存策略
private static LruPoolStrategy  getDefaultStrategy() {
    final LruPoolStrategy strategy ;
    if (Build.VERSION. SDK_INT >= Build.VERSION_CODES. KITKAT) {
        strategy =  new SizeConfigStrategy() ;
   else {
        strategy =  new AttributeStrategy() ;
    }
    return strategy ;
}

也是根据sdk版本不同的实现

@TargetApi(Build.VERSION_CODES. KITKAT)
public class SizeConfigStrategy  implements LruPoolStrategy {

class  AttributeStrategy  implements LruPoolStrategy {

他们两个都实现了LruPoolStrategy接口
看下这个接口
interface  LruPoolStrategy {
    void  put(Bitmap bitmap) ;
    Bitmap  get( int width , int height Bitmap.Config config) ;
    Bitmap  removeLast() ;
    String  logBitmap(Bitmap bitmap) ;
    String  logBitmap( int width , int height Bitmap.Config config) ;
    int  getSize(Bitmap bitmap) ;
}

看第get方法,是获得key的方式,width,height config
下面是 AttributeStrategy 的实现
下面是key的代码
static class Key  implements Poolable {
    private final KeyPool  pool ;
    private int  width ;
    private int  height ;
    // Config can be null :(
    private Bitmap.Config  config ;

    public Key(KeyPool pool) {
        this. pool = pool ;
    }

    public void  init( int width , int height Bitmap.Config config) {
        this. width = width ;
        this. height = height ;
        this. config = config ;
    }

    @Override
    public boolean  equals(Object o) {
        if (o  instanceof Key) {
            Key other = (Key) o ;
            return  width == other. width
                    &&  height == other. height
                    &&  config == other. config ;
        }
        return false;
    }

    @Override
    public int  hashCode() {
        int result =  width ;
        result =  31 * result +  height ;
        result =  31 * result + ( config !=  null config.hashCode() :  0) ;
        return result ;
    }

    @Override
    public String  toString() {
        return  getBitmapString( width height config) ;
    }

    @Override
    public void  offer() {
        pool.offer( this) ;
    }
}

AttributeStrategy实现的get和put实现方法

private final KeyPool  keyPool new KeyPool() ;
private final GroupedLinkedMap<Key Bitmap>  groupedMap new GroupedLinkedMap<Key Bitmap>() ;

public void  put(Bitmap bitmap) {
    final Key key =  keyPool.get(bitmap.getWidth() bitmap.getHeight() bitmap.getConfig()) ;

    groupedMap.put(key bitmap) ;
}

@Override
public Bitmap  get( int width , int height Bitmap.Config config) {
    final Key key =  keyPool.get(width height config) ;

    return  groupedMap.get(key) ;
}

这个是用了一个 GroupedLinkedMap
来存储的,里边的实现是和LinkedHashMap相似的方式,LinkedHashMap本身是有对LRU算法相应的实现的,读一下他的构造方法就明白了。

然后再看下cache
if ( memoryCache ==  null) {
    memoryCache new LruResourceCache(calculator.getMemoryCacheSize()) ;
}

默认是LruResourceCache
/**
 * An LRU in memory cache for { @link  com.bumptech.glide.load.engine.Resource}s.
 */
public class LruResourceCache  extends LruCache<Key Resource<?>>  implements MemoryCache {

咱们自己实现的cache要实现MemoryCache接口,把源码贴出来下
/**
 * An interface for adding and removing resources from an in memory cache.
 */
public interface MemoryCache {
    /**
     * An interface that will be called whenever a bitmap is removed from the cache.
     */
    interface ResourceRemovedListener {
        void  onResourceRemoved(Resource<?> removed) ;
    }

    /**
     * Returns the sum of the sizes of all the contents of the cache in bytes.
     */
    int  getCurrentSize() ;

    /**
     * Returns the current maximum size in bytes of the cache.
     */
    int  getMaxSize() ;

    /**
     * Adjust the maximum size of the cache by multiplying the original size of the cache by the given multiplier.
     *
     *  <p>
      *     If the size multiplier causes the size of the cache to be decreased, items will be evicted until the cache
     *     is smaller than the new size.
     *  </p>
      *
     *  @param  multiplier  A size multiplier >= 0.
     */
    void  setSizeMultiplier( float multiplier) ;

    /**
     * Removes the value for the given key and returns it if present or null otherwise.
     *
     *  @param  key  The key.
     */
    Resource<?>  remove(Key key) ;

    /**
     * Add bitmap to the cache with the given key.
     *
     *  @param  key  The key to retrieve the bitmap.
     *  @param  resource  The { @link  com.bumptech.glide.load.engine.EngineResource} to store.
     *  @return  The old value of key (null if key is not in map).
     */
    Resource<?>  put(Key key Resource<?> resource) ;

    /**
     * Set the listener to be called when a bitmap is removed from the cache.
     *
     *  @param  listener  The listener.
     */
    void  setResourceRemovedListener(ResourceRemovedListener listener) ;

    /**
     * Evict all items from the memory cache.
     */
    void  clearMemory() ;

    /**
     * Trim the memory cache to the appropriate level. Typically called on the callback onTrimMemory.
     *
     *  @param  level  This integer represents a trim level as specified in { @link  android.content.ComponentCallbacks2}.
     */
    void  trimMemory( int level) ;
}

默认实现的LruCache就是用的
private final LinkedHashMap<T, Y> cache = new LinkedHashMap<T, Y>(100, 0.75f, true);
/**
 * Constructs a new { @code  LinkedHashMap} instance with the specified
 * capacity, load factor and a flag specifying the ordering behavior.
 *
 *  @param  initialCapacity
  *            the initial capacity of this hash map.
 *  @param  loadFactor
  *            the initial load factor.
 *  @param  accessOrder
  *            { @code  true} if the ordering should be done based on the last
 *            access (from least-recently accessed to most-recently
 *            accessed), and { @code  false} if the ordering should be the
 *            order in which the entries were inserted.
 *  @throws  IllegalArgumentException
 *             when the capacity is less than zero or the load factor is
 *             less or equal to zero.
 */
public LinkedHashMap(
        int initialCapacity , float loadFactor , boolean accessOrder) {
    super(initialCapacity loadFactor) ;
    init() ;
    this. accessOrder = accessOrder ;
}
这个是LinkedHashMap的构造方法,lru方式或者默认插入顺序

if ( diskCacheFactory ==  null) {
    diskCacheFactory new InternalCacheDiskCacheFactory( context) ;
}

磁盘缓存的处理方式 需要实现 DiskCache接口
Glide给出了默认实现,注意一提的是,读写文件要注意读写一致的问题。如果有相关的可以参考下这里。

if ( engine ==  null) {
    engine new Engine( memoryCache diskCacheFactory diskCacheService sourceService) ;
}

这个Glide的引擎,目前的set方法还是test阶段,处理下载缓存等等的。
自己定义这个的话,就相当高级了,但是glide这边是支持扩展的哦。

if ( decodeFormat ==  null) {
    decodeFormat = DecodeFormat. DEFAULT ;
}

这个就是Bitmap的解码设置,默认是565的一个像素占2字节
/** The default value for DecodeFormat. */
public static final DecodeFormat  DEFAULT =  PREFER_RGB_565 ;

再来看下GlideModule怎么加载的,下面这个是Glide的创建
/**
 * Get the singleton.
 *
 *  @return  the singleton
 */
public static Glide  get(Context context) {
    if ( glide ==  null) {
        synchronized (Glide. class) {
            if ( glide ==  null) {
                Context applicationContext = context.getApplicationContext() ;
                List<GlideModule> modules =  new ManifestParser(applicationContext).parse() ;

                GlideBuilder builder =  new GlideBuilder(applicationContext) ;
                for (GlideModule module : modules) {
                    module.applyOptions(applicationContext builder) ;
                }
                glide = builder.createGlide() ;
                for (GlideModule module : modules) {
                    module.registerComponents(applicationContext glide) ;
                }
            }
        }
    }

    return  glide ;
}

这GlideModule可以有多个,在多个模块进行加载。

/**
 * Parses { @link  com.bumptech.glide.module.GlideModule} references out of the AndroidManifest file.
 */
public final class ManifestParser {
    private static final String  GLIDE_MODULE_VALUE "GlideModule" ;

    private final Context  context ;

    public ManifestParser(Context context) {
        this. context = context ;
    }

    public List<GlideModule>  parse() {
        List<GlideModule> modules =  new ArrayList<GlideModule>() ;
        try {
            ApplicationInfo appInfo =  context.getPackageManager().getApplicationInfo(
                    context.getPackageName() PackageManager. GET_META_DATA) ;
            if (appInfo. metaData !=  null) {
                for (String key : appInfo. metaData.keySet()) {
                    if ( GLIDE_MODULE_VALUE.equals(appInfo. metaData.get(key))) {
                        modules.add( parseModule(key)) ;
                    }
                }
            }
        }  catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException( "Unable to find metadata to parse GlideModules" e) ;
        }

        return modules ;
    }

    private static GlideModule  parseModule(String className) {
        Class<?> clazz ;
        try {
            clazz = Class. forName(className) ;
       catch (ClassNotFoundException e) {
            throw new IllegalArgumentException( "Unable to find GlideModule implementation" e) ;
        }

        Object module ;
        try {
            module = clazz.newInstance() ;
       catch (InstantiationException e) {
            throw new RuntimeException( "Unable to instantiate GlideModule implementation for " + clazz e) ;
       catch (IllegalAccessException e) {
            throw new RuntimeException( "Unable to instantiate GlideModule implementation for " + clazz e) ;
        }

        if (!(module  instanceof GlideModule)) {
            throw new RuntimeException( "Expected instanceof GlideModule, but found: " + module) ;
        }
        return (GlideModule) module ;
    }
}

这个是对Module进行获取信息和转换的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

method_chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值