天天看點

圖檔加載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加載圖檔的類型如圖所示:

圖檔加載8:Glide4配置和自定義子產品

圖檔.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)自定義擴充

圖檔加載8:Glide4配置和自定義子產品

圖檔.png

如圖所示,

myOverride

就是新增的擴充,使用注解

@GlideExtension

@GlideOption

可以添加擴充。

代碼如下:

@GlideExtension
public class MyGlideExtension {

    private MyGlideExtension() {

    }

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

}
           

繼續閱讀