图片加载8:Glide4配置和自定义模块

在4.0中不用像3.X需要在AndroidManifest.xml配置GlideModule,而是通过注解继承AppGlideModule的子类来配置。
自定义模块的出现,让Glide的使用更加灵活。

(1)依赖

Glide的使用需要用到的依赖是:

implementation 'com.github.bumptech.glide:glide:4.9.0'

但是,如果使用Glide自定义模块的话,还需要引用另一个依赖

annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'

(2)自定义模块

自定义模块需要使用注解@GlideModule,简单代码如下:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {

}

其中,MyAppGlideModule随便命名即可,AppGlideModule是Glide4的接口。

需要注意的是:

我们必须添加依赖annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0',否则自定义模块将无效,当我们重新编译时,就不会自动生成GlideApp

GlideApp如何使用?看一下代码就知道了

            //加载图片第一种写法
            Glide.with(this)
                    .load(url)
                    .into(image_view);

            //加载图片第二种写法
            GlideApp.with(this)
                    .load(url)
                    .into(image_view);

(3)如何禁止解析AndroidManifest.xml文件?

在自定义模块中,重写isManifestParsingEnabled方法,这个方式是Glide4为了向后兼容提供的方法,Glide3初始化时会解析AndroidManifest.xml文件,但是Glide4并不需要加载AndroidManifest.xml文件,如果使用Glide4,这里返回false即可。

返回值:
true: 依然解析AndroidManifest.xml文件
false: 不会解析AndroidManifest.xml文件

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {

    public MyAppGlideModule() {
        super();
    }

    @Override
    public boolean isManifestParsingEnabled() {
        return false;
    }
}

(4)Glide全局配置

在自定义模块中的applyOptions方法中可以添加全局配置。

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {

    public MyAppGlideModule() {
        super();
    }

    //全局配置Glide
    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {

    }
}

参数builder可以设置Glide配置,比如:

    //设置Bitmap的缓存池
    builder.setBitmapPool(new LruBitmapPool(30));

    //设置内存缓存
    builder.setMemoryCache(new LruResourceCache(30));

    //设置磁盘缓存
    builder.setDiskCache(new InternalCacheDiskCacheFactory(context));

    //设置读取不在缓存中资源的线程
    builder.setResizeExecutor(GlideExecutor.newSourceExecutor());

    //设置读取磁盘缓存中资源的线程
    builder.setDiskCacheExecutor(GlideExecutor.newDiskCacheExecutor());

    //设置日志级别
    builder.setLogLevel(Log.VERBOSE);

    //设置全局选项
    RequestOptions requestOptions = new RequestOptions();
    requestOptions.format(DecodeFormat.PREFER_RGB_565);
    builder.setDefaultRequestOptions(requestOptions);

(5)注册组件

自定义模块中的registerComponents方法的参数registry可以注册新的组件

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {

    public MyAppGlideModule() {
        super();
    }
    //注册自定义组件
    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        
    }
}

组件是干什么用的?

组件可以确定图片加载的类型已经加载方式。Glide加载图片的类型如图所示:

图片.png

其中每一种类型都有对应的组件。

我们找一下源码中的组件,如下:

registry
    .append(ByteBuffer.class, new ByteBufferEncoder())
    .append(InputStream.class, new StreamEncoder(arrayPool))
    /* Bitmaps */
    .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
    .append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder)
    .append(
        Registry.BUCKET_BITMAP,
        ParcelFileDescriptor.class,
        Bitmap.class,
        parcelFileDescriptorVideoDecoder)
    .append(
        Registry.BUCKET_BITMAP,
        AssetFileDescriptor.class,
        Bitmap.class,
        VideoDecoder.asset(bitmapPool))
    .append(Bitmap.class, Bitmap.class, UnitModelLoader.Factory.<Bitmap>getInstance())
    .append(
        Registry.BUCKET_BITMAP, Bitmap.class, Bitmap.class, new UnitBitmapDecoder())
    .append(Bitmap.class, bitmapEncoder)
    /* BitmapDrawables */
    .append(
        Registry.BUCKET_BITMAP_DRAWABLE,
        ByteBuffer.class,
        BitmapDrawable.class,
        new BitmapDrawableDecoder<>(resources, byteBufferBitmapDecoder))
    .append(
        Registry.BUCKET_BITMAP_DRAWABLE,
        InputStream.class,
        BitmapDrawable.class,
        new BitmapDrawableDecoder<>(resources, streamBitmapDecoder))
    .append(
        Registry.BUCKET_BITMAP_DRAWABLE,
        ParcelFileDescriptor.class,
        BitmapDrawable.class,
        new BitmapDrawableDecoder<>(resources, parcelFileDescriptorVideoDecoder))
    .append(BitmapDrawable.class, new BitmapDrawableEncoder(bitmapPool, bitmapEncoder))
    /* GIFs */
    .append(
        Registry.BUCKET_GIF,
        InputStream.class,
        GifDrawable.class,
        new StreamGifDecoder(imageHeaderParsers, byteBufferGifDecoder, arrayPool))
    .append(Registry.BUCKET_GIF, ByteBuffer.class, GifDrawable.class, byteBufferGifDecoder)
    .append(GifDrawable.class, new GifDrawableEncoder())
    /* GIF Frames */
    // Compilation with Gradle requires the type to be specified for UnitModelLoader here.
    .append(
        GifDecoder.class, GifDecoder.class, UnitModelLoader.Factory.<GifDecoder>getInstance())
    .append(
        Registry.BUCKET_BITMAP,
        GifDecoder.class,
        Bitmap.class,
        new GifFrameResourceDecoder(bitmapPool))
    /* Drawables */
    .append(Uri.class, Drawable.class, resourceDrawableDecoder)
    .append(
        Uri.class, Bitmap.class, new ResourceBitmapDecoder(resourceDrawableDecoder, bitmapPool))
    /* Files */
    .register(new ByteBufferRewinder.Factory())
    .append(File.class, ByteBuffer.class, new ByteBufferFileLoader.Factory())
    .append(File.class, InputStream.class, new FileLoader.StreamFactory())
    .append(File.class, File.class, new FileDecoder())
    .append(File.class, ParcelFileDescriptor.class, new FileLoader.FileDescriptorFactory())
    // Compilation with Gradle requires the type to be specified for UnitModelLoader here.
    .append(File.class, File.class, UnitModelLoader.Factory.<File>getInstance())
    /* Models */
    .register(new InputStreamRewinder.Factory(arrayPool))
    .append(int.class, InputStream.class, resourceLoaderStreamFactory)
    .append(
        int.class,
        ParcelFileDescriptor.class,
        resourceLoaderFileDescriptorFactory)
    .append(Integer.class, InputStream.class, resourceLoaderStreamFactory)
    .append(
        Integer.class,
        ParcelFileDescriptor.class,
        resourceLoaderFileDescriptorFactory)
    .append(Integer.class, Uri.class, resourceLoaderUriFactory)
    .append(
        int.class,
        AssetFileDescriptor.class,
        resourceLoaderAssetFileDescriptorFactory)
    .append(
        Integer.class,
        AssetFileDescriptor.class,
        resourceLoaderAssetFileDescriptorFactory)
    .append(int.class, Uri.class, resourceLoaderUriFactory)
    .append(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())
    .append(Uri.class, InputStream.class, new DataUrlLoader.StreamFactory<Uri>())
    .append(String.class, InputStream.class, new StringLoader.StreamFactory())
    .append(String.class, ParcelFileDescriptor.class, new StringLoader.FileDescriptorFactory())
    .append(
        String.class, AssetFileDescriptor.class, new StringLoader.AssetFileDescriptorFactory())
    .append(Uri.class, InputStream.class, new HttpUriLoader.Factory())
    .append(Uri.class, InputStream.class, new AssetUriLoader.StreamFactory(context.getAssets()))
    .append(
        Uri.class,
        ParcelFileDescriptor.class,
        new AssetUriLoader.FileDescriptorFactory(context.getAssets()))
    .append(Uri.class, InputStream.class, new MediaStoreImageThumbLoader.Factory(context))
    .append(Uri.class, InputStream.class, new MediaStoreVideoThumbLoader.Factory(context))
    .append(
        Uri.class,
        InputStream.class,
        new UriLoader.StreamFactory(contentResolver))
    .append(
        Uri.class,
        ParcelFileDescriptor.class,
         new UriLoader.FileDescriptorFactory(contentResolver))
    .append(
        Uri.class,
        AssetFileDescriptor.class,
        new UriLoader.AssetFileDescriptorFactory(contentResolver))
    .append(Uri.class, InputStream.class, new UrlUriLoader.StreamFactory())
    .append(URL.class, InputStream.class, new UrlLoader.StreamFactory())
    .append(Uri.class, File.class, new MediaStoreFileLoader.Factory(context))
    .append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
    .append(byte[].class, ByteBuffer.class, new ByteArrayLoader.ByteBufferFactory())
    .append(byte[].class, InputStream.class, new ByteArrayLoader.StreamFactory())
    .append(Uri.class, Uri.class, UnitModelLoader.Factory.<Uri>getInstance())
    .append(Drawable.class, Drawable.class, UnitModelLoader.Factory.<Drawable>getInstance())
    .append(Drawable.class, Drawable.class, new UnitDrawableDecoder())

以上自带的组件有很多,比如

.append(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())

第一个参数表示,Glide可以加载String类型的数据,第二个参数表示采用输入流的方式读取数据,第三个参数就是数据加载工厂。

自定义组件可以让程序员随意的制定加载类型,假如我们想加载一个Photo对象也能加载图片,代码如下:

            //加载网络图片
            Photo photo = new Photo();
            photo.setUrl("http://pic32.nipic.com/20130823/13339320_183302468194_2.jpg");
            GlideApp.with(this)
                    .load(photo)
                    .into(image_view);

由于Glide本身并不支持加载Photo对象,要想让以上代码可以正常加载图片,那么我们必须自定义一个组件,自定义组件代码如下:

public class Photo {

    private String url;


    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

}
public class PhotoModelLoader extends BaseGlideUrlLoader<Photo> {

    public static class Factory implements ModelLoaderFactory<Photo, InputStream> {

        private final ModelCache<Photo, GlideUrl> modelCache = new ModelCache<Photo, GlideUrl>(500);

        @Override
        public ModelLoader<Photo, InputStream> build(MultiModelLoaderFactory multiFactory) {
            return new PhotoModelLoader(multiFactory.build(GlideUrl.class, InputStream.class),
                    modelCache);
        }

        @Override
        public void teardown() {
        }
    }

    protected PhotoModelLoader(ModelLoader<GlideUrl, InputStream> concreteLoader) {
        super(concreteLoader);
    }

    protected PhotoModelLoader(ModelLoader<GlideUrl, InputStream> concreteLoader, @Nullable ModelCache<Photo, GlideUrl> modelCache) {
        super(concreteLoader, modelCache);
    }

    @Override
    protected String getUrl(Photo photo, int width, int height, Options options) {
        return photo.getUrl();
    }

    @Override
    public boolean handles(Photo photo) {
        return true;
    }

}
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {

    public MyAppGlideModule() {
        super();
    }
    
    //注册自定义组件
    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        registry.append(Photo.class, InputStream.class,new PhotoModelLoader.Factory());
    }
}

(6)自定义扩展

图片.png

如图所示,myOverride就是新增的扩展,使用注解@GlideExtension@GlideOption可以添加扩展。

代码如下:

@GlideExtension
public class MyGlideExtension {

    private MyGlideExtension() {

    }

    @GlideOption
    public static BaseRequestOptions<?> myOverride(BaseRequestOptions<?> options) {
        options.override(500, 500);
        return options;
    }

}
发布了122 篇原创文章 · 获赞 30 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qijingwang/article/details/101269984