Glide 提供了许多可应用于单一请求的选项,包括变换、过渡、缓存选项等。
1.默认选项可以直接应用于请求上:
GlideApp.with(this).load(uri)
.placeholder(R.mipmap.sc2)
.error(R.mipmap.sc1)
.override(150)
.circleCrop().into(agb.ivOptions);
2.通过 RequestOptions 类来在多个请求之间共享:
RequestOptions requestOptions = new RequestOptions().circleCrop()
.placeholder(R.mipmap.sc2)
.error(R.mipmap.sc1).override(150);
GlideApp.with(this).load(uri).apply(requestOptions).into(agb.ivOptions);
GlideApp.with(this).load(uri).apply(requestOptions).into(agb.ivCirclecrop);
GlideExtension
Glide Generated API 可在 Application 和 Library 中被扩展。扩展使用被注解的静态方法来添加新的选项、修改现有选项、甚至添加额外的类型支持。
被 @GlideExtension 注解的类应以工具类的思维编写。这种类应该有一个私有的、空的构造方法,应为 final 类型,并且仅包含静态方法。被注解的类可以含有静态变量,可以引用其他的类或对象。
被 @GlideExtention 注解的类有两种扩展方式:
-
GlideOption - 为 RequestOptions 添加一个自定义的选项。
-
GlideType - 添加对新的资源类型的支持(GIF,SVG 等等)。
GlideOption
1.创建一个添加有 @GlideExtension注解的类。此类可生成出一个流式 API,内联了多种选项和集成库中自定义的选项:
@GlideExtension
public final class MyGlideExtension {
private MyGlideExtension(){}
@GlideOption
public static BaseRequestOptions<?> applyHeadScc(BaseRequestOptions<?> options,int size){
return options.circleCrop()
.override(size)
.placeholder(R.mipmap.sc2)
.error(R.mipmap.sc1);
}
}
2.这将在RequestOptions子类中生成一个如下所示的方法:
public class GlideOptions extends RequestOptions {
/**
* @see MyGlideExtension#applyHeadScc(BaseRequestOptions, int)
*/
@SuppressWarnings(“unchecked”)
@CheckResult
@NonNull
public GlideOptions applyHeadScc(int size) {
return (GlideOptions) MyGlideExtension.applyHeadScc(this, size);
}
…
}
3.可以根据需要在方法中包含任意数量的附加参数,只要第一个参数始终为RequestOptions:
@GlideOption
public static BaseRequestOptions<?> applyHeadScc(BaseRequestOptions<?> options,int size){
return options.circleCrop()
.override(size)
.placeholder(R.mipmap.sc2)
.error(R.mipmap.sc1);
}
4.附加参数将作为参数添加到生成的方法中:
public GlideOptions applyHeadScc(int size) {
return (GlideOptions) MyGlideExtension.applyHeadScc(this, size);
}
5.使用生成的GlideApp类调用你的自定义方法:
GlideApp.with(this)
.load(uri)
.applyHeadScc(150)
.into(agb.ivOptions);
带有GlideOption注释的方法应该是静态的并返回BaseRequestOptions< ? >。 注意: 生成的方法在标准Glide和RequestOptions类上不可用,只有Generated 的等效项可用。
高斯模糊(效果图)
1.使用库 传送门
implementation ‘jp.wasabeef:glide-transformations:4.3.0’
开始使用
@GlideOption
public static BaseRequestOptions<?> applyBlurHeadScc(BaseRequestOptions<?> options,int size){
BlurTransformation blurTransformation = new BlurTransformation(20,1);
return options
.override(size)
.placeholder(R.mipmap.sc2)
.error(R.mipmap.sc1)
// .circleCrop()
// .transform(blurTransformation);
// .transform(blurTransformation,new CircleCrop());
.transform(new MultiTransformation<>(blurTransformation,new CircleCrop()));
}
注意: 默认情况下,对每一个后续呼叫transform()或任何特定的transform方法(fitCenter(),centerCrop(),bitmapTransform()等)将取代先前的transform。
要将多个转换应用于单个加载,请使用MultiTransformation类或快捷 .transforms() 方法。
2.自定义Transformation 你也可以继承BitmapTransformation,重写transform方法,下面贴出glide-transformations里面的BlurTransformation类,一起学习一下。
public class BlurTransformation extends BitmapTransformation {
private static final int VERSION = 1;
private static final String ID =
“jp.wasabeef.glide.transformations.BlurTransformation.” + VERSION;
private static final int MAX_RADIUS = 25;
private static final int DEFAULT_DOWN_SAMPLING = 1;
private final int radius;
private final int sampling;
public BlurTransformation() {
this(MAX_RADIUS, DEFAULT_DOWN_SAMPLING);
}
public BlurTransformation(int radius) {
this(radius, DEFAULT_DOWN_SAMPLING);
}
public BlurTransformation(int radius, int sampling) {
this.radius = radius;
this.sampling = sampling;
}
@Override
protected Bitmap transform(@NonNull Context context, @NonNull BitmapPool pool,
@NonNull Bitmap toTransform, int outWidth, int outHeight) {
int width = toTransform.getWidth();
int height = toTransform.getHeight();
int scaledWidth = width / sampling;
int scaledHeight = height / sampling;
Bitmap bitmap = pool.get(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
setCanvasBitmapDensity(toTransform, bitmap);
Canvas canvas = new Canvas(bitmap);
canvas.scale(1 / (float) sampling, 1 / (float) sampling);
Paint paint = new Paint();
paint.setFlags(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(toTransform, 0, 0, paint);
try {
bitmap = RSBlur.blur(context, bitmap, radius);
} catch (RSRuntimeException e) {
bitmap = FastBlur.blur(bitmap, radius, true);
}
return bitmap;
}
@Override
public String toString() {
return “BlurTransformation(radius=” + radius + “, sampling=” + sampling + “)”;
}
@Override
public boolean equals(Object o) {
return o instanceof BlurTransformation &&
((BlurTransformation) o).radius == radius &&
((BlurTransformation) o).sampling == sampling;
}
@Override
public int hashCode() {
return ID.hashCode() + radius * 1000 + sampling * 10;
}
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
messageDigest.update((ID + radius + sampling).getBytes(CHARSET));
}
}
GlideType
GlideType带注释的静态方法扩展RequestManager。GlideType带注释的方法允许您添加对新类型的支持,包括指定默认选项。
1.例如,要添加对 GIF 的支持(选择资源类型),你可以添加一个GlideType方法:
@GlideType(GifDrawable.class)
public static RequestBuilder scGif(RequestBuilder requestBuilder) {
return requestBuilder
.transition(new DrawableTransitionOptions())
.apply(decodeTypeOf(GifDrawable.class).lock());
}
方法名为什么叫scGif,而不是asGif,因为GlideRequests中已经有一个asGif方法。
2.将在GlideRequests生成一个如下所示的方法:
public class GlideRequests extends RequestManager {
public GlideRequest scGif() {
return (GlideRequest) MyGlideExtension.scGif(this.as(GifDrawable.class));
}
…
}
3.使用生成的GlideApp类来调用您的自定义类型(选择资源类型):
GlideApp.with(this)
.scGif()
.load(uri)
.applyBlurHeadScc(150)
.addListener(new RequestListener() {
@Override
public boolean onLoadFailed(GlideException e, Object model, Target target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GifDrawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(agb.ivCirclecrop);
RequestListener 返回的类型为你scGif设置的GifDrawable 相对应。
submit同步获取图片资源
FutureTarget target= GlideApp.with(this)
.asBitmap()
.load(uri)
.applyBlurHeadScc(150)
.submit();
//因target.get()是同步请求
//所以用线程转异步请求
new Thread(new Runnable() {
@Override
public void run() {
try {
Bitmap bitmap = target.get();//同步请求
//子线程切主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
agb.ivOptions.setImageBitmap(bitmap);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
效果跟之前的一样一样的。 这个功能就是有特殊需求时对获取的图片进行特殊处理。
Application Options(选项)
=======================
Glide 允许应用通过 AppGlideModule 实现来完全控制 Glide 的内存和磁盘缓存使用。Glide 试图提供对大部分应用程序合理的默认选项,但对于部分应用,可能就需要定制这些值。在你做任何改变时,请注意测量其结果,避免出现性能的倒退。
Memory cache(内存缓存)
默认情况下,Glide使用 LruResourceCache ,这是 MemoryCache 接口的一个缺省实现,使用固定大小的内存和 LRU 算法。LruResourceCache 的大小由 Glide 的 MemorySizeCalculator 类来决定,这个类主要关注设备的内存类型,设备 RAM 大小,以及屏幕分辨率。
1.自定义 MemoryCache 的大小,具体是在它们的 AppGlideModule 中使用 applyOptions(Context, GlideBuilder) 方法配置 MemorySizeCalculator:
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
MemorySizeCalculator calculator = new MemorySizeCalculator.Builder(context)
.setMemoryCacheScreens(2)
.build();
builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize()));
}
}
2.直接覆盖缓存大小:
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
int memoryCacheSizeBytes = 1024 * 1024 * 10; // 10mb
builder.setMemoryCache(new LruResourceCache(memoryCacheSizeBytes));
}
}
3.提供自己的 MemoryCache 实现:
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setMemoryCache(new MyMemoryCacheImpl());
}
}
Disk Cache(磁盘缓存)
Glide 使用 DiskLruCacheWrapper 作为默认的磁盘缓存。 DiskLruCacheWrapper 是一个使用 LRU 算法的固定大小的磁盘缓存。默认磁盘大小为 250 MB ,位置是在应用的 缓存文件夹 中的一个 特定目录 。
1.如果显示的媒体是公开的(从未经身份验证的网站、搜索引擎等获取),则应用程序可以将位置更改为外部存储:
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDiskCache(new ExternalCacheDiskCacheFactory(context));
}
}
2.无论使用内部或外部磁盘缓存,应用程序都可以改变磁盘缓存的大小:
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
int diskCacheSizeBytes = 1024 * 1024 * 100; // 100 MB
builder.setDiskCache(new InternalCacheDiskCacheFactory(context, diskCacheSizeBytes));
}
}
3.应用程序还可以改变缓存文件夹在外存或内存上的名字:
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
int diskCacheSizeBytes = 1024 * 1024 * 100; // 100 MB
builder.setDiskCache(
new InternalCacheDiskCacheFactory(context, “cacheFolderName”, diskCacheSizeBytes));
}
}
**4.应用程序还可以自行选择 DiskCache 接口的实现,并提供自己的 DiskCache.Factory 来创建缓存。**Glide 使用一个工厂接口来在后台线程中打开 磁盘缓存 ,这样方便缓存做诸如检查路径存在性等的IO操作而不用触发 严格模式 。
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDiskCache(new DiskCache.Factory() {
@Override
public DiskCache build() {
return new MyCustomDiskCache();
}
});
}
}
Bitmap pool(位图池)
Glide 使用 LruBitmapPool 作为默认的 BitmapPool 。LruBitmapPool 是一个内存中的固定大小的 BitmapPool,使用 LRU 算法清理。默认大小基于设备的分辨率和密度,同时也考虑内存类和 isLowRamDevice 的返回值。具体的计算通过 Glide 的 MemorySizeCalculator 来完成,与 Glide 的 MemoryCache 的大小检测方法相似。
1.可以在它们的 AppGlideModule 中定制 BitmapPool 的尺寸,使用 applyOptions(Context, GlideBuilder) 方法并配置 MemorySizeCalculator:
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
MemorySizeCalculator calculator = new MemorySizeCalculator.Builder(context)
.setBitmapPoolScreens(3)
.build();
builder.setBitmapPool(new LruBitmapPool(calculator.getBitmapPoolSize()));
}
}
2.直接复写这个池的大小:
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
int bitmapPoolSizeBytes = 1024 * 1024 * 30; // 30mb
builder.setBitmapPool(new LruBitmapPool(bitmapPoolSizeBytes));
}
}
3.提供自己的BitmapPool实现:
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setBitmapPool(new MyBitmapPoolImpl());
}
}
配置缓存
====
磁盘缓存策略(Disk Cache Strategy)
DiskCacheStrategy 可被 diskCacheStrategy 方法应用到每一个单独的请求。 目前支持的策略允许你阻止加载过程使用或写入磁盘缓存,选择性地仅缓存无修改的原生数据,或仅缓存变换过的缩略图,或是兼而有之。
指定 DiskCacheStrategy 非常容易:
Glide.with(this)
.load(uri)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
写在最后
最后我想说:对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
che Strategy)
DiskCacheStrategy 可被 diskCacheStrategy 方法应用到每一个单独的请求。 目前支持的策略允许你阻止加载过程使用或写入磁盘缓存,选择性地仅缓存无修改的原生数据,或仅缓存变换过的缩略图,或是兼而有之。
指定 DiskCacheStrategy 非常容易:
Glide.with(this)
.load(uri)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
写在最后
最后我想说:对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
[外链图片转存中…(img-zB9sb8At-1714125764455)]
[外链图片转存中…(img-NlV2K6sF-1714125764456)]
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!