Android图片缓存之Glide进阶(四)
前言:
前面学习了Glide的简单使用(http://www.cnblogs.com/whoislcj/p/5558168.html),今天来学习一下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的结合,已经简单探析一下内部使用。
Android图片缓存之Glide进阶(四)的更多相关文章
- Android图片缓存之Glide进阶
前言: 前面学习了Glide的简单使用(Android图片缓存之初识Glide),今天来学习一下Glide稍微复杂一点的使用. 图片缓存相关博客地址: Android图片缓存之Bitmap详解 And ...
- Android图片缓存框架Glide
Android图片缓存框架Glide Glide是Google提供的一个组件.它具有获取.解码和展示视频剧照.图片.动画等功能.它提供了灵活的API,帮助开发者将Glide应用在几乎任何网络协议栈中. ...
- Android图片缓存之初识Glide
前言: 前面总结学习了图片的使用以及Lru算法,今天来学习一下比较优秀的图片缓存开源框架.技术本身就要不断的更迭,从最初的自己使用SoftReference实现自己的图片缓存,到后来做电商项目自己的实 ...
- 安卓高级 Android图片缓存之初识Glide
前言: 前面总结学习了图片的使用以及Lru算法,今天来学习一下比较优秀的图片缓存开源框架.技术本身就要不断的更迭,从最初的自己使用SoftReference实现自己的图片缓存,到后来做电商项目自己的实 ...
- Android图片缓存之Lru算法
前言: 上篇我们总结了Bitmap的处理,同时对比了各种处理的效率以及对内存占用大小.我们得知一个应用如果使用大量图片就会导致OOM(out of memory),那该如何处理才能近可能的降低oom发 ...
- Android图片缓存之Bitmap详解
前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap.BitmapFactory这两个类. 图片缓存相关博客地址: Android图片缓 ...
- Android图片缓存之初识Glide(三)
前言: 前面总结学习了图片的使用以及Lru算法,今天来学习一下比较优秀的图片缓存开源框架.技术本身就要不断的更迭,从最初的自己使用SoftReference实现自己的图片缓存,到后来做电商项目自己的实 ...
- android 图片缓存
一.Picasso https://github.com/square/picasso Picasso是Square公司开源的一个Android平台上的图片加载框架,简单易用,一句话搞定项目中的图片加 ...
- android图片缓存(包含ReusableBitmapDrawable和BitmapPool)
现在做的项目中,有用到一个开源的2D地图框架osmdroid,但是在项目中,使用还是有一些问题,例如,多个地图实例,会有独自的图片缓存,Activity onPause时,并不会释放图片缓存,如果多级 ...
随机推荐
- Hadoop4.2HDFS测试报告之四
第二组:文件存储读过程记录 测试系统组成 存储类型 测试程序或命令 测试文件大小(Mb) 文件个数(个) 客户端并发数(个) 读速率 (M/s) NameNode:1 DataNode:1 本地存储 ...
- Python之多线程与多进程(二)
多进程 上一章:Python多线程与多进程(一) 由于GIL的存在,Python的多线程并没有实现真正的并行.因此,一些问题使用threading模块并不能解决 不过Python为并行提供了一个替代方 ...
- canvas 动画库 CreateJs 之 EaselJS(上篇)
本文来自网易云社区 作者:田亚楠 须知 本文主要是根据 createjs 中的 EaselJS 在 github 上的 tutorials 目录下的文章整理而来 (原文链接),同时也包含了很多本人的理 ...
- jquery拼接字符串
1. $("#div").append("<table><tr align='center'>" +"<td >& ...
- Balanced Lineup(ST)
描述 For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. On ...
- C#拆箱和装箱成本
从原理上可以看出,装箱时,生成的是全新的引用对象,这会有时间损耗,也就是造成效率降低. 文章:.Net常见面试题整理(2)——装箱和拆箱 装箱,产生新的引用对象,并且赋值,然后引用. 拆箱,往往跟随着 ...
- 解决Failure to transfer org.apache.maven.plugins:maven-surefire-plugin:pom:2.7
一般情况下可能是文件格式有问题,将正确的文件内容替换掉错误的文件内容,不断地尝试,直到文件不报错,当然也有可能是下面的原因:下面是2.7.1版本的方法,其他类似) 或者是:进入该jar包指示的路径,删 ...
- Linux Shell系列教程之(八)Shell printf命令详解
本文是Linux Shell系列教程的第(八)篇,更多shell教程请看:Linux Shell系列教程 在上一篇:Linux Shell系列教程之(七)Shell输出这篇文章中,已经对Shell p ...
- java面试题之谈谈你对java的理解
平台无关性:一处编译到处运行 GC:不用像c++那样手动释放堆内容 语言特性:泛型.反射.lamda表达式 面向对象:封装.继承.多态 类库:集合.并发库.网络库.IO库 异常处理
- 解决v-for产生的警告的办法
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略.如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且 ...