设置Gradle
repositories {
mavenCentral()
maven { url 'https://maven.google.com' }
}
dependencies {
compile 'com.github.bumptech.glide:glide:4.1.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.1.1'
}
Maven
<dependency>
<groupId>com.github.bumptech.glidegroupId>
<artifactId>glideartifactId>
<version>4.1.1version>
<type>aartype>
dependency>
<dependency>
<groupId>com.google.androidgroupId>
<artifactId>support-v4artifactId>
<version>r7version>
dependency>
<dependency>
<groupId>com.github.bumptech.glidegroupId>
<artifactId>compilerartifactId>
<version>4.1.1version>
<optional>trueoptional>
dependency>
Proguard 混淆
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
Kotlin
dependencies {
kapt 'com.github.bumptech.glide:compiler:4.1.1'
}
简单用法,和之前版本没区别
Glide.with(fragment)
.load(myUrl)
.into(imageView);
取消已下载的图片:
Glide.with(fragment).clear(imageView);
注:当Activity或Fragment被销毁时,Glide会自动清理缓存。clear 在ListView/RecycleView中需要替换图片的时候可以用上。
引用GlideApp:
自定义类继承AppGlideModule,package中会自动生成GlideApp类,然后我们就可以用GlideApp.with()代替Glide.with()了
package com.example.myapp;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}
GlideApp.with(fragment)
.load(myUrl)
.fitCenter()
.into(imageView);
placeHolder占位图:图片未加载时显示
GlideApp.with(fragment)
.load(url)
.placeholder(R.drawable.placeholder)
//.placeholder(new ColorDrawable(Color.BLACK))
.into(view);
error:图片加载失败时显示
GlideApp.with(fragment)
.load(url)
.error(R.drawable.error)
//.error(new ColorDrawable(Color.RED))
.into(view);
fallback:url/model为null时显示
GlideApp.with(fragment)
.load(url)
.fallback(R.drawable.fallback)
//.fallback(new ColorDrawable(Color.GREY))
.into(view);
RequestOptions 可添加四种参数: Placeholders、Transformations、Caching Strategies 以及组件特定的选项(编码质量,Bitmap解码设置)
Glide.with(fragment)
.load(url)
.apply(centerCropTransform(context))
.into(imageView);、
RequestOptions cropOptions = new RequestOptions().centerCrop(context);
...
Glide.with(fragment)
.load(url)
.apply(cropOptions)
.into(imageView);
注:RequestOptions可以被共享,apply()也可以多次调用,如果两个RequestOptions包含冲突设置,则后一个会覆盖前一个。
TransitionOptions 可添加三种参数:View淡入、交叉淡入淡出、没有任何效果:
Glide.with(fragment)
.load(url) .transition(DrawableTransitionOptions.withCrossFade())//淡入淡出
.into(view);
注: TransitionOptions分为 BitmapTransitionOptions 和
DrawableTransitionOptions
RequestBuilder:用来整合options,图片的类型(Drawable/Bitmap)、url/model、需加载资源的view、RequestOption、TransitionOptions、thumbnail()
RequestBuilder requestBuilder = Glide.with(fragment);
requestBuilder.apply(requestOptions);
requestBuilder.transition(transitionOptions);
RequestOptions options = new RequestOptions();
options.centerCrop();
Glide.with(fragment)
.load(url)
.apply(options)
.into(imageView);
RequestBuilders可以被重复使用
RequestBuilder requestBuilder =
Glide.with(fragment)
.asDrawable()
.apply(requestOptions);
for (int i = 0; i < numViews; i++) {
ImageView view = viewGroup.getChildAt(i);
String url = urls.get(i);
requestBuilder.load(url).into(view);
}
Transformations: CenterCrop、FitCenter、CircleCrop
Glide.with(fragment)
.load(url)
.apply(options)//RequestOptions
.apply(fitCenterTransform())//静态方法
.fitCenter()//generated API
.into(imageView);
Targets:glide 的回调 ,封装了当图片请求完成后会调用的方法
@Override
public void onResourceReady(Object resource, Transition transition) {
}
@Override
public void getSize(SizeReadyCallback cb) {
}
@Override
public void removeCallback(SizeReadyCallback cb) {
}
Target target = Glide.with(fragment)
.asBitmap()
.load(url)
.into(imageView);
...
// 记得clear
Glide.with(fragment).clear(target);
自定义target:
简单的作为实例变量
private class WidgetHolder {
private final Fragment fragment;
private final Target widgetTarget;
public WidgetHolder(Fragment fragment, Widget widget) {
this.fragment = fragment;
widgetTarget = new CustomWidgetTarget(widget);
}
public void showInWidget(Uri uri) {
Glide.with(fragment)
.load(uri)
.into(widgetTarget);
}
}
注:
- Glide能够使用getRequest()和setRequest()方法查找和取消对Targets的请求。所以可以继承BaseTarget.
- Glide优先使用由Targets提供的getSize()大小作为请求的目标大小
Transformations转换:
CenterCrop:缩放图像,使图像的宽度与给定的宽度匹配,并且图像的高度大于给定的高度,反之亦然,然后裁剪较大的尺寸以匹配给定的尺寸。不保持图像的纵横比
FitCenter:使图像均匀(保持图像的纵横比),使图像的尺寸之一等于给定的尺寸,另一个将小于给定的尺寸。
CircleCrop:,绕圈裁剪一个图像,所产生的图像被蒙上一个圆圈
RequestOptions options = new RequestOptions();
options.centerCrop();
Glide.with(fragment)
.load(url)
.apply(options)
.into(imageView);
import static com.bumptech.glide.request.RequestOptions.fitCenterTransform;
Glide.with(fragment)
.load(url)
.apply(fitCenterTransform())
.into(imageView);
GlideApp.with(fragment)
.load(url)
.fitCenter()
.into(imageView);
Mutiple Transformations :多重转换按顺序执行
Glide.with(fragment)
.load(url)
.transform(new MultiTransformation(new FitCenter(), new YourCustomTransformation())
.into(imageView);
或
GlideApp.with(fragment)
.load(url)
.transforms(new FitCenter(), new YourCustomTransformation())
.into(imageView);
注:
- 最好创建Transformation一次,然后将其传递给多个加载。
- glide会根据图片的比例类型(如:FIT_CENTER、CENTER_INSIDE)自动转换
- 适用Bitmap Transformations于BitmapDrawable,GifDrawable和Bitmap
Transitions 动画:
- 单次网络请求中占位图与加载图的转变或图片尺寸的转变。
- 与v3不同,v4没有默认转变,每次请求都要定义。
- 如果从Glide的内存缓存中加载数据,则Glide的内置转换不会运行。但是,如果从Glide的磁盘缓存,本地源文件或Uri或远程源Url或Uri加载数据,则Glide的内置转换将会运行。如果要改变可自定义transition。
- 使用动画会使加载看起来缓慢,应尽量避免在列表时使用动画,必须要用时使用预加载
Configuration:为了使Glide的配置正常工作,库和应用程序需要执行一定步骤。不注册其他组件的库不需要这样做。
Libraries():
- 添加一个或多个LibraryGlideModule实现。
- 将@GlideModule注释添加到每个LibraryGlideModule实现
- 在Glide的注释处理器上添加依赖关系。
以okhttp为例:
@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());
}
}
使用@GlideModule注释需要依赖于Glide的注释:
compile 'com.github.bumptech.glide:annotations:4.1.1'
Applications:
- 添加一个AppGlideModule实现
- 可选地,添加一个或多个LibraryGlideModule实现。
- 将@GlideModule注释添加到AppGlideModule和所有LibraryGlideModule。
- 在Glide的注释处理器上添加依赖关系。
- 为AppGlideModules添加混淆。
glidesamples有个Flickr的例子:
@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());
}
}
注释依赖:
compile 'com.github.bumptech.glide:annotations:4.1.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.1.1'
混淆添加到proguard.cfg:
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep class com.bumptech.glide.GeneratedAppGlideModuleImpl
Glide允许应用程序通过实现AppGlideModule来完全控制Glide的内存和磁盘缓存的使用。
自定义内存缓存:LruResourceCache是MemoryCache的默认实现interface,LruResourceCache通过MemorySizeCalculator这个检查设备内存的类来确定size。
@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()));
}
}
//or 直接覆盖缓存大小
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
int memoryCacheSizeBytes = 1024 * 1024 * 20; // 20mb
builder.setMemoryCache(new LruResourceCache(memoryCacheSizeBytes));
}
}
//or 自己实现MemoryCache
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setMemoryCache(new YourAppMemoryCacheImpl());
}
}
磁盘缓存:DiskLruCacheWrapper默认磁盘缓存大小为250 MB,并放置在应用程序的缓存文件夹中的特定目录中。
改成外部磁盘存储:
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDiskCache(new ExternalDiskCacheFactory(context));
}
}
改变磁盘大小:
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
int diskCacheSizeBytes = 1024 * 1024 * 100; // 100 MB
builder.setDiskCache(new InternalDiskCacheFactory(context, diskCacheSizeBytes));
}
}
更改存储文件夹名:
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
int diskCacheSizeBytes = 1024 * 1024 * 100; // 100 MB
builder.setDiskCache(
new InternalDiskCacheFactory(context, "cacheFolderName", diskCacheSizeBytes));
}
}
设置默认requestoptions
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDefaultRequestOptions(
new RequestOptions()
.format(DecodeFormat.RGB_565)
.disallowHardwareBitmaps());
}
}
注:有冲突设置,builder中的option会被覆盖
为activity或fragment单独设置默认requestoptions:
Glide.with(fragment)
.applyDefaultRequestOptions(
new RequestOptions()
.format(DecodeFormat.RGB_565)
.disallowHardwareBitmaps());
注册组件:
1. ModelLoader加载自定义模型(Urls,Uris,任意POJO)和Data(InputStreams,FileDescriptors)。
2. ResourceDecoder以解码新的资源(Drawables,Bitmaps)或新类型的数据(InputStreams,FileDescriptors)。
3. Encoders将Data(InputStreams,FileDescriptors)写入Glide的磁盘缓存。
4. ResourceTranscoder将资源(BitmapResource)转换为其他类型的资源(DrawableResource)。
5. ResourceEncoder将资源(BitmapResource,DrawableResource)写入Glide的磁盘缓存。
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
registry.append(...);
}
}
//or
@GlideModule
public class YourLibraryGlideModule extends LibraryGlideModule {
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
registry.append(...);
}
}
例:一个可以获取新的自定义Model对象的InputStream的ModelLoader
//append()将确保你的的ModelLoader或ResourceDecoder仅在Glide的默认值尝试之后才会调用。
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
registry.append(Photo.class, InputStream.class, new CustomModelLoader.Factory());
}
}
//prepend()将确保你的ModelLoader或ResourceDecoder在所有其他先前注册的组件之前被调用,并且可以先运行。
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
registry.prepend(String.class, InputStream.class, new CustomUrlModelLoader.Factory());
}
}
//replace()完全替代Glide的默认行为并确保它不会运行。适用于像OkHttp或Volley这样的库来交换Glide的网络逻辑
@GlideModule
public class YourAppGlideModule extends AppGlideModule {
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
}
}
冲突排除:
@Excludes({com.example.unwanted.GlideModule.class, com.example.conflicing.GlideModule.class})
@GlideModule
public final class MyAppGlideModule extends AppGlideModule { }
注:从Glide v3迁移过程中,可以将其用于排除LibraryGlideModules旧版和旧版的GlideModule实现。
Glide v4可以完全禁用清单解析。这样做可以改善Glide的初始启动时间,并避免尝试分析元数据时出现一些潜在的问题。
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {
@Override
public boolean isManifestParsingEnabled() {
return false;
}
}
Caching 高速缓存:默认情况下,Glide会在启动对图像的新请求之前检查多层缓存:
- 活跃资源 - 此图像是否显示在另一个视图中?
- 内存缓存 - 这张图像最近是否加载并仍在内存中?
- 资源 - 此图像是否已经被解码,转换和写入磁盘缓存之前?
- 数据 - 此图像是否从写入磁盘缓存获取的数据?
前两个步骤检查资源是否在内存中,如果是,请立即返回图像。第二个步骤检查图像是否在磁盘上,并快速返回,但异步。
如果所有四个步骤都找不到图像,则Glide将返回原始来源以检索数据(原始文件,Uri,Url等)。
磁盘缓存策略:默认为DiskCacheStrategy.AUTOMATIC,加载远程数据时,只存储原始数据,加载本地数据时,存储缩略图。DiskCacheStrategy有五种值:
DiskCacheStrategy.ALL 使用DATA和RESOURCE缓存远程数据,仅使用RESOURCE来缓存本地数据。
DiskCacheStrategy.NONE 不使用磁盘缓存
DiskCacheStrategy.DATA 将原始数据写入磁盘缓存
DiskCacheStrategy.RESOURCE 在资源解码后将数据(缩略图)写入磁盘缓存。
DiskCacheStrategy.AUTOMATIC 根据原始图片数据和资源编码策略来自动选择磁盘缓存策略。
GlideApp.with(fragment)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
只从缓存加载
GlideApp.with(fragment)
.load(url)
.onlyRetrieveFromCache(true)
.into(imageView);
跳过缓存加载
GlideApp.with(fragment)
.load(url)
.skipMemoryCache(true)//跳过内存缓存
.diskCacheStrategy(DiskCacheStrategy.NONE)//跳过磁盘缓存
.into(view);
暂时允许Glide在应用的某些部分使用更多或更少的内存:
Glide.get(context).setMemoryCategory(MemoryCategory.LOW);
// Or:
Glide.get(context).setMemoryCategory(MemoryCategory.HIGH);
//离开后需重新设置内存
Glide.get(context).setMemoryCategory(MemoryCategory.NORMAL);
清除内存缓存
// This method must be called on the main thread.
Glide.get(context).clearMemory();
清除磁盘缓存
new AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
// This method must be called on a background thread.
Glide.get(applicationContext).clearDiskCache();
return null;
}
}
Debugging:
Glide.with(fragment)
.load(url)
.listener(new RequestListener() {
@Override
boolean onLoadFailed(@Nullable GlideException e, Object model,
Target target, boolean isFirstResource) {
// Log errors here.
}
@Override
boolean onResourceReady(R resource, Object model, Target target,
DataSource dataSource, boolean isFirstResource) {
// Log successes here or use DataSource to keep track of cache hits and misses.
}
})
.into(imageView);