Glide简单使用(四)

1.用Modules()定制Glide
概述:Glide module是一个抽象方法,可以全局改变Glide行为的一个方式,
如果需要访问GlideBuider,需要创建Glide实例,定制Glide,需要实现一个GlideModule接口的公共类。

public class SimpleGlideModule implements GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // todo
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        // todo
    }
}

可以看到GlideModule里面有两种方法,这个我们到后面再来讲。
定制完成类之后,下一步是要全局的去声明这个类,让Glide知道应该在哪里被加载和使用。Glide会去扫描AndroidManifest.xml为GlideModule的meta声明。


<application>
  <meta-data
            android:name="test.demo.SimpleGlideModule"
            android:value="GlideModule" />
  </application>          

这个android:name注意,属性明是,你这包名+类名的形式。如果你想删除该配置,直接在AndroidManifest.xml删除meta-data就OK。
我们去定制Module的Glide有个优点:你可以同时声明多个Glide module。Glide(没有特定顺序)得到所有的声明module。因为当前不能定义顺序,请确保定制不会引起冲突!


GlideBuilder

这里写图片描述

我们从上图可以看出GlideBuilder中的几个方法。
在这就说一下**.setDecodeFormat(DecodeFormat decodeFormat)方法。
可以设置Glide的图片质量
我们应该知道在android中有两种方法对图片进行解码:PREFER_ARGB_8888
PREFER_RGB_565**。前者每个像素使用了4个字节,后者每像素使用2个字节。可以知道前者图片质量更高,更能存储一个alpha通道。Glide默认使用RGB_565。如果使用者想改变解码规则。看代码

   @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // todo
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    }

2.自定义内存缓存
其实分为:

  • 内存缓存
  • 磁盘缓存
    内存缓存:是在设备的RAM中去维护图片的。没有IO操作,所以是很快的。但是RAM(内存)的大小非常有限。所以Glide内存使用了MemorySizeCalculator 类去决定内存缓存大小以及bitmap的缓存池。bitmap池维护了APP的堆中的图像分配。正确的bitmap池是非常必要的,因为它避免很多的图像重复回收,这样可以确保垃圾回收期的管理更加合理。
  MemorySizeCalculator calculator = new MemorySizeCalculator(context);
        //1.获取内存缓存的大小与Bitmap位图池的大小
        int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
        int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
        //2.app 需要 20% 大的缓存作为 Glide 的默认值
        int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
        int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);

        builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize));
        builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize));

我们现在所看到的,在builder设置的时候,不能直接设置大小,我们需要创建LruResourceCacheLruBitmapPool实例。如果想要调整大小,我们只需要传两个不同的大小值给构造函数。

磁盘缓存

  • 内部磁盘缓存
    • APP自己能访问 **InternalCacheDiskCacheFactory **
    • 应用外部也能访问 ExternalCacheDiskCacheFactory
  • 外部磁盘缓存 DiskLruCacheFactory
    • 外部添加
    • 外部添加目录名称

具体我们看代码吧:

    int cacheSize100MegaBytes = 104857600;
        //设置内部缓存,只有当前APP有访问权限
        builder.setDiskCache(
                new InternalCacheDiskCacheFactory(context, cacheSize100MegaBytes)
        );
        //设置外部缓存,不止它自己能访问
        builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, cacheSize100MegaBytes));

        // or any other path
        String downloadDirectoryPath = Environment.getDownloadCacheDirectory().getPath();
        //如果你要让磁盘缓存到指定的目录,你要使用 DiskLruCacheFactory:
        builder.setDiskCache(
                new DiskLruCacheFactory(downloadDirectoryPath, cacheSize100MegaBytes)
        );
        //如果您想要指定一个缓存到自己设置的文件名
        builder.setDiskCache(
                new DiskLruCacheFactory(downloadDirectoryPath, "glidecache", cacheSize100MegaBytes)
        );

3.Module 实例:用自定义尺寸优化加载的图片
概述:当图像质量非常高时,可想而知对于设备的网速,内存和电池来说,这么做效率非常低。就算我们的手机屏幕分辨率非常高,也没有任何好处。所以Glide总是测量ImageView的尺寸,并减少图像的内存分配大小。这里任然需要减少下载和计算处理的开销。因此服务端给了一个细腻功能:它可以自动自定义图像的分辨率。

http://u-jia.deyi.com/2016/12/20/.jpg

http://u-jia.deyi.com/2016/12/20/.jpg?w=641&h=422

其实这个w(宽)h(高)就是,ImageView的宽高。我这测试的时候,发现当我们使用了.override(500, 300)属性,这个时候图片就会使用(500,300)当做图片的宽高,不再使用ImageView的宽高。可以自行测试。

自定义GlideModule
首先,必须声明一个新的Glidemodule,我们必须用glide.register() 方法注册新的 model 到 Glide。

public class CustomImageSizeGlideModule implements GlideModule {  
    @Override public void applyOptions(Context context, GlideBuilder builder) {
        // nothing to do here
    }

    @Override public void registerComponents(Context context, Glide glide) {
        glide.register(CustomImageSizeModel.class, InputStream.class, new CustomImageSizeModelFactory());
    }
}

从上可以看到,我们glide.register使用了,CustomImageSizeModel接口(替换常规的GlideUrL接口)。所以在这里你可以创建并传递一个 CustomImageSizeModel 的实例去实现给 Glide。 为了处理这个新的自定义 model。我们要去写一个 CustomImageSizeModelFactory 类,创建了我们的 model 处理的实例。

public interface CustomImageSizeModel {  
    String requestCustomSizeUrl(int width, int height);
}

CustomImageSizeModel 只是一个接口,它将宽度和高度作为其参数,这是必须的,这样我们才能从服务端请求精确的像素图像。第二个未知的类是 CustomImageSizeModelFactory:

private class CustomImageSizeModelFactory implements ModelLoaderFactory<CustomImageSizeModel, InputStream> {  
    @Override
    public ModelLoader<CustomImageSizeModel, InputStream> build(Context context, GenericLoaderFactory factories) {
        return new CustomImageSizeUrlLoader( context );
    }

    @Override
    public void teardown() {

    }
}

这个类仅仅实现了 Glide 的 ModelLoaderFactory 接口。它为我们的 CustomImageSizeUrlLoader 类创建了一个新的实例,一旦 Glide 请求被创建,它将负责加载图像。

public class CustomImageSizeUrlLoader extends BaseGlideUrlLoader<CustomImageSizeModel> {  
    public CustomImageSizeUrlLoader(Context context) {
        super( context );
    }

    @Override
    protected String getUrl(CustomImageSizeModel model, int width, int height) {
        return model.requestCustomSizeUrl( width, height );
    }
}

这样,我们为自定义大小的请求的新的 Glide module 已经做完了。我们已经在 Glide module 这边实现了所有的东西的,但是我们还没有实际创建 CustomImageSizeModel 接口的实现。为了用 CustomImageSizeModel 传递请求给 Glide。我们需要一个雷,它建立了自定义图片大小的 URL:

public class CustomImageSizeModelFutureStudio implements CustomImageSizeModel {  
    String baseImageUrl;

    public CustomImageSizeModelFutureStudio(String baseImageUrl) {
        this.baseImageUrl = baseImageUrl;
    }

    @Override
    public String requestCustomSizeUrl(int width, int height) {
        // previous way: we directly accessed the images
        // https://futurestud.io/images/logo.png

        // new way, server could handle additional parameter and provide the image in a specific size
        // in this case, the server would serve the image in 400x300 pixel size
        // https://futurestud.io/images/logo.png?w=400&h=300
        return baseImageUrl + "?w=" + width + "&h=" + height;
    }
}

在上面的 CustomImageSizeModelFutureStudio 类中,我们已经实现了建立图片 URL 的逻辑:附加了高度和宽度的参数。最后,我们可以创建这个类的实例并做一个 Glide 请求:

String baseImageUrl = "http://u-jia.deyi.com/2016/12/21/1e06021b5d6c86fcb69a8041eec000e5aa280f48_640x426.jpg";  
CustomImageSizeModel customImageRequest = new CustomImageSizeModelFutureStudio( baseImageUrl );

Glide  
        .with( context )
        .load( customImageRequest )
        .into( imageView2 );

我们可以看到,我们不需要传一个精确的尺寸,Glide会测量ImageView然后传给我们的请求。


Model Loader 和 .using() 的动态使用
如果我们声明了Glidemodule,Glide会把它用在每一个请求。如果不想这样 ,可以从AndroidManifest.xml 中删除你的 Glide module。因为Glide提供了 .using()方法为单个请求指定一个model。

  String baseImageUrl = "http://u-jia.deyi.com/2016/12/21/1e06021b5d6c86fcb69a8041eec000e5aa280f48_640x426.jpg";
        CustomImageSizeModel modelFutureStudio =
                new CustomImageSizeModelFutureStudio(baseImageUrl);
        Glide.with(getApplicationContext())
                .using(new CustomImageSizeUrlLoader(getApplicationContext()))
                .load(modelFutureStudio)
                .into(iv_12);

正如你看到的,我们正在创建一个 CustomImageSizeModelFutureStudio 对象来为我们的图像按照指定的大小加载。因为没有在 Glide module 中声明 CustomImageSizeModel 接口,我们必须指明这行代码 .using(new CustomImageSizeUrlLoader(context))。Glide 现在会只为这个请求用这个 model。对于其他的请求,即使它们有 CustomImageSizeModel 接口,也不会受影响。

原文地址:
https://mrfu.me/2016/02/28/Glide_How_to_Rotate_Images/
DEMO地址:
https://github.com/z244370114/GlideDemo

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

怀君

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

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

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

打赏作者

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

抵扣说明:

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

余额充值