Glide start up 安装 1 2 3 4 5 6 7 8 9 10 11 12 13 plugins { id 'org.jetbrains.kotlin.kapt' } dependencies { implementation("com.github.bumptech.glide:glide:4.15.1" ) kapt("com.github.bumptech.glide:compiler:4.15.1" ) }
基础使用
加载图片
1 2 3 Glide.with(fragment) .load(myUrl) .into(imageView);
取消加载
1 Glide.with(fragment).clear(imageView);
自定义request
Glide提供独立的请求,包含transformations
,transitions
,caching
通常的默认请求可0配置直接使用
1 2 3 4 5 Glide.with(fragment) .load(myUrl) .placeholder(placeholder) .fitCenter() .into(imageView);
当然我们也可以进行自定义
1 2 3 4 5 6 7 8 9 RequestOptions sharedOptions = new RequestOptions () .placeholder(placeholder) .fitCenter(); Glide.with(fragment) .load(myUrl) .apply(sharedOptions) .into(imageView1);
自定义Target
Glide不仅支持将Bitmap
和View
而且还支持异步装入自定义Target
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Glide.with(context) .load(url) .into(new CustomTarget <Drawable>() { @Override public void onResourceReady (Drawable resource, Transition<Drawable> transition) { } @Override public void onLoadCleared (@Nullable Drawable placeholder) { } });
后台装入 1 2 3 4 5 FutureTarget<Bitmap> futureTarget = Glide.with(context) .asBitmap() .load(url) .submit(width, height);
Placeholder
Glide支持设置3种不同的占位符
配置
Glide大部分的配置可以通过RequestBuilder
配置
相关的配置包括
Placeholder
Transformations
cache strategies
Component specific options, like encode quality, or decode Bitmap
configurations
RequestOptions
如果我们想要对一部分内容做抽象的时候,我们可以初始化一个RequestOptions
对象,并通过apply传入到每一个需要复用的Glide中。
1 2 3 4 5 6 RequestOptions cropOptions = new RequestOptions ().centerCrop(context);... Glide.with(fragment) .load(url) .apply(cropOptions) .into(imageView);
TransitionOptions
TransitionOptions
决定了请求加载完毕以后之后会发生什么。
使用TransitionOptions
View fade in
Cross fade from placeholder
No transition
1 2 3 4 5 6 import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;Glide.with(fragment) .load(url) .transition(withCrossFade()) .into(view);
RequestBuilder
RequestBuilder
是request的主干,用于将option和我们所请求的url等信息合并在一起,并开启一个新的加载
使用RequestBuilder
可以获取
加载资源的类型
url/资源的来源
资源加载进的view
需要进行配置的RequestOption
需要进行配置的TransitionOption
thumbnail
效果的配置
选取资源类型
选择bitmap类型
1 RequestBuilder<Bitmap> requestBuilder = Glide.with(fragment).asBitmap();
apply配置 1 2 3 RequestBuilder<Drawable> requestBuilder = Glide.with(fragment).asDrawable(); requestBuilder.apply(requestOptions); requestBuilder.transition(transitionOptions);
加载缩略图
thumbnail
支持并行开启请求,thumbnail支持本地和远端图片,特别是当缩略图处于Glide缓存内加载会特别迅速
1 2 3 4 5 6 Glide.with(fragment) .load(url) .thumbnail( Glide.with(fragment) .load(thumbnailUrl)) .into(imageView);
Transformatations用于获取一个资源并对资源做变动,通常变动可以是裁剪,过滤或者对一些动画GIF做转换。
内置的Transformations包含
CenterCrop
FitCenter
CircleCrop
Transformation基础使用
1 2 3 4 Glide.with(fragment) .load(url) .fitCenter() .into(imageView);
1 2 3 4 5 6 7 Glide.with(this ) .load(R.drawable.ic_launcher_background) .apply( RequestOptions() .circleCrop() ) .into(binding.ivImage)
Multiple Transformations
1 2 3 4 Glide.with(fragment) .load(url) .transform(new MultiTransformation (new FitCenter (), new YourCustomTransformation ()) .into(imageView);
1 2 3 4 Glide.with(fragment) .load(url) .transform(new FitCenter (), new YourCustomTransformation ()) .into(imageView);
自定义Transformations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 private class MyBitmapTransformation extends BitmapTransformation { public MyBitmapTransformation (Context context) { super (context); } @Override protected Bitmap transform (BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { Canvas canvas = new Canvas (toTransform); BitmapShader bitmapShader = new BitmapShader (toTransform, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); int min = Math.min(toTransform.getWidth(), toTransform.getHeight()); int radius = min / 2 ; RadialGradient radialGradient = new RadialGradient (toTransform.getWidth() / 2 , toTransform.getHeight() / 2 , radius, Color.TRANSPARENT, Color.WHITE, Shader.TileMode.CLAMP); ComposeShader composeShader = new ComposeShader (bitmapShader, radialGradient, PorterDuff.Mode.SRC_OVER); Paint paint = new Paint (); paint.setShader(composeShader); canvas.drawRect(0 , 0 , toTransform.getWidth(), toTransform.getHeight(), paint); return toTransform; } @Override public String getId () { return "MyBitmapTransformation" ; } }
Targets
Targets作为请求和请求者的中间者,Targets可以用于负责展示占位符,加载的资源,或是用于决定每一个请求的View宽高,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Glide.with(this ) .load("" ) .into(object : CustomViewTarget<ImageView, Drawable>() { override fun onLoadFailed (errorDrawable: Drawable?) { TODO("Not yet implemented" ) } override fun onResourceCleared (placeholder: Drawable?) { TODO("Not yet implemented" ) } override fun onResourceReady ( resource: Drawable, transition: Transition<in Drawable>? ) { TODO("Not yet implemented" ) } })
ImageView
内有内置的Target
即——ImageViewTarget
1 2 3 4 Target<Drawable> target = Glide.with(fragment) .load(url) .into(imageView);
取消和重用
Glide
的into方法会返回一个Target
对象的实例,当我们复用Target
进行数据的加载的时候会将以往的Target
取消
1 2 3 4 5 6 7 8 9 10 11 Target<Drawable> target = Glide.with(fragment) .load(url) .into(new Target <Drawable>() { ... }); ... Glide.with(fragment) .load(newUrl) .into(target);
清除
1 2 3 4 5 6 7 8 9 Target<Drawable> target = Glide.with(fragment) .load(url) .into(new Target <Drawable>() { ... }); ... Glide.with(fragment).clear(target);
Transitions
Transition定义了Glide如何从一个placeholder转变为一个图片的动画特效或者从缩略图到一个全量大学的图片
Transitions通常用于单个请求的转换,而不是横跨多个请求。
Transition的实例化可以通过TransitionOptions
声明,并通过RequestBuilder的transition
方法指定request的transition。
默认的有提供BitmapTransitionOptions
或者DrawableTransitionOptions
自定义Transition
继承TransitionFactory
通过DrawableTransitionOptions#with
方法指定transition
Configuration Application
使用步骤如下
只能添加一个AppGlideModule
添加一个或者更多的LibraryGlideModule
添加@GlideModule
注解给AppGlideModule
和其他的LibraryGlideModule
添加Glide apt依赖
1 2 3 4 5 6 7 @GlideModule public class FlickrGlideModule extends AppGlideModule { @Override public void registerComponents (Context context, Glide glide, Registry registry) { registry.append(Photo.class, InputStream.class, new FlickrModelLoader .Factory()); } }
options
Glide Application的选项有
1 2 3 4 5 6 7 8 9 10 11 @GlideModule public class YourAppGlideModule 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())); } }
1 2 3 4 5 6 7 8 9 10 @GlideModule public class YourAppGlideModule 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())); } }
1 2 3 4 5 6 7 @GlideModule public class YourAppGlideModule extends AppGlideModule { @Override public void applyOptions (Context context, GlideBuilder builder) { builder.setDiskCache(new ExternalCacheDiskCacheFactory (context)); } }
1 2 3 4 5 6 7 8 9 10 @GlideModule public class YourAppGlideModule extends AppGlideModule { @Override public void applyOptions (Context context, GlideBuilder builder) { builder.setDefaultRequestOptions( new RequestOptions () .format(DecodeFormat.RGB_565) .disallowHardwareBitmaps()); } }
UncaughtThrowableStrategy
1 2 3 4 5 6 7 8 9 @GlideModule public class YourAppGlideModule extends AppGlideModule { @Override public void applyOptions (Context context, GlideBuilder builder) { final UncaughtThrowableStrategy myUncaughtThrowableStrategy = new ... builder.setDiskCacheExecutor(newDiskCacheExecutor(myUncaughtThrowableStrategy)); builder.setResizeExecutor(newSourceExecutor(myUncaughtThrowableStrategy)); } }
1 2 3 4 5 6 7 @GlideModule public class YourAppGlideModule extends AppGlideModule { @Override public void applyOptions (Context context, GlideBuilder builder) { builder.setLogLevel(Log.DEBUG); } }
Libirary
LibraryGlideModule
可以用于注册自定义的组件,例如ModuleLoader
添加一个或者多个LibraryGlideModule
添加@Glide
注解
添加apt依赖
1 2 3 4 5 6 7 @GlideModule public final class OkHttpLibraryGlideModule extends LibraryGlideModule { @Override public void registerComponents (Context context, Glide glide, Registry registry) { registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader .Factory()); } }
数据解析
Glide相关的数据解析分为如下几步
Model -> Data (handled by ModelLoaders
)
Data -> Resource (handled by ResourceDecoders
)
Resource -> Transcoded Resource (optional, handled by ResourceTranscoders
).
prepend()
、append()
、replace()
方法用于设置GlideModule的尝试顺序
最先加载的是通过prepend
设置的ModuleLoader
或者ResourceDecorder
再者就是append添加的ModuleLoader
或者ResourceDecoder
replace
方法可用于替换内置的ModuleLoader
或者ResourceDecoder
Conflicts
试想假如你现在有一个GlideModule
定义在你自己的模块里面
当我们使用的依赖中也包含AppGlideModule
的时候这时候可用的AppGlideModule
就有两个了,超过了最大数,我们称之为冲突
我们可以通过@Excludes
添加冲突时候的排除选项
如下我们通过Excludes注解排除了com.example.unwanted.GlideModule
1 2 3 @Excludes(com.example.unwanted.GlideModule.class) @GlideModule public final class MyAppGlideModule extends AppGlideModule { }
Manifest Parsing
早期版本的Glide v3有对Manifest文件进行解析,为了保证向后兼容,新版本也没有对这个特性修改
不过我们可以通过AppGlideModule设置是否加载
1 2 3 4 5 6 7 @GlideModule public final class MyAppGlideModule extends AppGlideModule { @Override public boolean isManifestParsingEnabled () { return false ; } }
Cache缓存
默认情况下Glide有如下缓存
Active resources
刚被其他View加载的缓存
Memory cache
View虽然不是刚加载的,但是仍然保存在内存中
Resource
内存中没有缓存了,但是图片经由Decode,Transform已经写入磁盘
Data
前面的缓存均无,查看raw data数据是否在磁盘中
前两步是查看缓存是否在内存中(同步且迅速),后两步查看缓存是否在磁盘中(异步且缓慢)。
Key
在Glide 4 所有的Cache Key包含至少两个部分
数据模型(Uri,File,Url),如果使用的是自定义的Model,需要实现hashCode
或者equals
方法
可选的签名
上述1-3部分缓存包含
宽高
可选的Transformation
添加的Options
请求的数据类型(Bitmap,GIF,其他)
缓存配置
1 2 3 4 Glide.with(fragment) .load(url) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(imageView);
1 2 3 4 Glide.with(fragment) .load(url) .onlyRetrieveFromCache(true ) .into(imageView);
1 2 3 4 Glide.with(fragment) .load(url) .skipMemoryCache(true ) .into(view);
or
1 2 3 4 Glide.with(fragment) .load(url) .diskCacheStrategy(DiskCacheStrategy.NONE) .into(view);
1 2 3 4 Glide.with(yourFragment) .load(yourFileDataModel) .signature(new ObjectKey (yourVersionMetadata)) .into(yourImageView);
1 2 3 4 5 Glide.get(context).setMemoryCategory(MemoryCategory.LOW); Glide.get(context).setMemoryCategory(MemoryCategory.HIGH); Glide.get(context).setMemoryCategory(MemoryCategory.NORMAL);
1 2 Glide.get(context).clearMemory();
1 2 3 4 5 6 7 8 new AsyncTask <Void, Void, Void> { @Override protected Void doInBackground (Void... params) { Glide.get(applicationContext).clearDiskCache(); return null ; } }
总结 Glide 可用的API较多有
placeholder
transformation
transition
cache
configuration
options
RequestOptions
TransitionOptions
RequestBuilder
Component Options
target
但是上述只有一项是Glide的核心。
即Bitmap。
别忘了Glide的出现是为了解决图片的问题,图片太大 占内存,图片频繁加载 内存抖动。
Cache和图片压缩是为了减少内存的波动,减少GC次数从而提升性能。