zoukankan      html  css  js  c++  java
  • Android图片缓存之Glide进阶

    前言:

         前面学习了Glide的简单使用(Android图片缓存之初识Glide),今天来学习一下Glide稍微复杂一点的使用。

     图片缓存相关博客地址:

    GlideModule使用:

           GlideModule 是一个抽象方法,全局改变 Glide 行为的一个方式,通过全局GlideModule 配置Glide,用GlideBuilder设置选项,用Glide注册ModelLoader等。

      1.)自定义一个GlideModule 

    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.
        }
    }

      2.)AndroidManifest.xml注册

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

      3.)添加混淆处理

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

      4.)多个GlideModule冲突问题

       GlideModule不能指定调用顺序,所以应该避免不同的GlideModule之间有冲突的选项设置,可以考虑将所有的设置都放到一个GlideModule里面,或者排除掉某个manifest文件的某个Module,代码如下:

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

    GlideBuilder设置选项:

    1.)设置Glide内存缓存大小

     int maxMemory = (int) Runtime.getRuntime().maxMemory();//获取系统分配给应用的总内存大小
     int memoryCacheSize = maxMemory / 8;//设置图片内存缓存占用八分之一
     //设置内存缓存大小
     builder.setMemoryCache(new LruResourceCache(memoryCacheSize));

      获取默认的内存使用计算函数

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

    2.)设置Glide磁盘缓存大小

     File cacheDir = context.getExternalCacheDir();//指定的是数据的缓存地址
     int diskCacheSize = 1024 * 1024 * 30;//最多可以缓存多少字节的数据
     //设置磁盘缓存大小
     builder.setDiskCache(new DiskLruCacheFactory(cacheDir.getPath(), "glide", diskCacheSize));

     也可以通过如下两种方式

      //存放在data/data/xxxx/cache/
      builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide", diskCacheSize));
      //存放在外置文件浏览器
      builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, "glide", diskCacheSize));

    3.)设置图片解码格式

    //设置图片解码格式
    builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);

    默认格式RGB_565使用内存是ARGB_8888的一半,但是图片质量就没那么高了,而且不支持透明度

    4.)设置缓存内存大小

     //设置BitmapPool缓存内存大小
      builder.setBitmapPool(new LruBitmapPool(memoryCacheSize));

    5.)设置一个用来检索cache中没有的Resource的ExecutorService

    为了使缩略图请求正确工作,实现类必须把请求根据Priority优先级排好序。

    builder.setDiskCacheService(ExecutorService service);
    builder.setResizeService(ExecutorService service);

    使用ModelLoader自定义数据源:

    例如我们使用了七牛云存储,要根据不同的要求请求不同尺寸不同质量的图片,这时我们就可以使用自定义数据源

      1.)定义处理URL接口

    public interface IDataModel {
    
        String buildDataModelUrl(int width, int height);
    
    }

    2.)实现处理URL接口

    JpgDataModel
    public class JpgDataModel implements IDataModel {
        private String dataModelUrl;
    
        public JpgDataModel(String dataModelUrl) {
            this.dataModelUrl = dataModelUrl;
        }
    
        @Override
        public String buildDataModelUrl(int width, int height) {
            //http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg?imageView2/1/w/200/h/200/format/jpg
            return String.format("%s?imageView2/1/w/%d/h/%d/format/jpg", dataModelUrl, width, height);
        }
    }
    WebpDataModel
    public class WebpDataModel implements IDataModel {
        private String dataModelUrl;
    
        public WebpDataModel(String dataModelUrl) {
            this.dataModelUrl = dataModelUrl;
        }
    
        @Override
        public String buildDataModelUrl(int width, int height) {
            //http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg?imageView2/1/w/200/h/200/format/webp
            return String.format("%s?imageView2/1/w/%d/h/%d/format/webp", dataModelUrl, width, height);
        }
    }

    3.)实现ModelLoader

    public class MyDataLoader extends BaseGlideUrlLoader<IDataModel> {
        public MyDataLoader(Context context) {
            super(context);
        }
    
        public MyDataLoader(ModelLoader<GlideUrl, InputStream> urlLoader) {
            super(urlLoader, null);
        }
    
        @Override
        protected String getUrl(IDataModel model, int width, int height) {
            return model.buildDataModelUrl(width, height);
        }
    
        /**
         */
        public static class Factory implements ModelLoaderFactory<IDataModel, InputStream> {
    
            @Override
            public ModelLoader<IDataModel, InputStream> build(Context context, GenericLoaderFactory factories) {
                return new MyDataLoader(factories.buildModelLoader(GlideUrl.class, InputStream.class));
            }
    
            @Override
            public void teardown() {
            }
        }
    }

    4.)根据不同的要求采用不同的策略加载图片

       //加载jpg图片
       Glide.with(this).using(new MyDataLoader(this)).load(new JpgDataModel(imageUrl)).into(imageView);
       //加载webp图片
       Glide.with(this).using(new MyDataLoader(this)).load(new WebpDataModel(imageUrl)).into(imageView);

    5.)如何跳过.using()

    public class MyGlideModule implements GlideModule {
        ...
        @Override
        public void registerComponents(Context context, Glide glide) {
            glide.register(IDataModel.class, InputStream.class, 
                new MyUrlLoader.Factory());
        }
    }

    上面的实现跳过using()

       //加载jpg图片
       Glide.with(this).load(new JpgDataModel(imageUrl)).into(imageView);
       //加载webp图片
       Glide.with(this).load(new WebpDataModel(imageUrl)).into(imageView);

     使用signature()实现自定义cacheKey:

        Glide 以 url、viewwidth、viewheight、屏幕的分辨率等做为联合key,官方api中没有提供删除图片缓存的函数,官方提供了signature()方法,将一个附加的数据加入到缓存key当中,多媒体存储数据,可用MediaStoreSignature类作为标识符,会将文件的修改时间、mimeType等信息作为cacheKey的一部分,通过改变key来实现图片失效相当于软删除。

    1.)使用StringSignature

    Glide.with(this).load(yourFileDataModel).signature(new StringSignature("1.0.0")).into(imageView);

    2.)使用MediaStoreSignature

    Glide.with(this) .load(mediaStoreUri).signature(new MediaStoreSignature(mimeType, dateModified, orientation)).into(view);

    3.)使用自定义Signature

    public class IntegerVersionSignature implements Key {
      private int currentVersion;
      public IntegerVersionSignature(int currentVersion) {
         this.currentVersion = currentVersion;
      }
      @Override
      public boolean equals(Object o) {
        if (o instanceof IntegerVersionSignature) {
          IntegerVersionSignature other = (IntegerVersionSignature) o;
          return currentVersion = other.currentVersion;
        }
        return false;
      }
      @Override
      public int hashCode() {
        return currentVersion;
      }
      @Override
      public void updateDiskCacheKey(MessageDigest md) {
        messageDigest.update(ByteBuffer.allocate(Integer.SIZE)
    .putInt(signature).array());
      }
    }

    小结:

         今天学了Glide的一些自定义扩展知识,接下来学习一下Glide与OKHttp的结合,已经简单探析一下内部使用。

  • 相关阅读:
    eclipse插件开发的打包
    零部件表设计 T_AIS_BASE_PARTS_INFO
    配送计划导入子表设计
    eclipse插件开发流程
    互联网公司的规律.txt
    用户 'sa' 登录失败。 连接SQL2000出现的问题。
    JAVA分页总结
    分类信息网络应用
    关于FLEX中找不到目标对象或通道未定义错误
    即时通讯IM的安全性比较
  • 原文地址:https://www.cnblogs.com/whoislcj/p/5565012.html
Copyright © 2011-2022 走看看