乐趣区

关于android:Android-图片加载框架Glide

Android 图片加载框架 Glide

一:概述
Glide 是目前在 Android 的开发中十分的受欢迎,简直是轻易开一个我的项目都会想到应用 Glide 当图片加载框架
1. 次要特点:
(1)反对 Memory 和 Disk 图片缓存
(2)反对 gif 和 webp 格局图片
(3)依据 Activity/Fragment 生命周期主动治理申请
(4)应用 Bitmap Pool 能够应用 Bitmap 复用
(5)对于回收的 Bitmap 会被动调用 recycle,缩小零碎回收压力
2. 依赖
高版本

// 这是对于 Glide 4 的依赖和之前 Glide 有一些区别
 implementation 'com.github.bumptech.glide:glide:4.11.0'
  annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
  // 相比于 Glide 3,这里要多增加一个 compiler 的库,这个库是用于生成 Generated API 的

对于 Kolin
如果你在 Kotlin 编写的类里应用 Glide 注解,你须要引入一个 kapt 依赖,以代替惯例的 annotationProcessor 依赖

dependencies {
 implementation 'com.github.bumptech.glide:glide:4.11.0'
 kapt 'com.github.bumptech.glide:compiler:4.11.0'
}

低版本

implementation 'com.github.bumptech.glide:glide:3.7.0'

咱们针对于 Glide 3 的一些办法应用解说
二:根本应用
在 AndroidManifest 文件增加权限
<uses-permission android:name=”android.permission.INTERNET”/>


public class ElevenActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btn;
    private ImageView imageView;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_eleven);
        imageView= findViewById(R.id.iv_img);
        btn=findViewById(R.id.btn_click);
        btn.setOnClickListener(this::onClick);
    }

    @Override
    public void onClick(View v) {
        String url = "http://guolin.tech/book.png";
        Glide.with(this).load(url).into(imageView);//Glide 申请加载图片的最简略
    }
}

1. 加载图片

Glide.with(this).load(url).into(imageView);


加载网络图片,从文件中加载,加载资源 id 等

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"Test.jpg");
Glide.with(context).load(file).into(imageViewFile);

2. 占位符 placeholder 加载时候未加载进去前先有一个占位图,error 加载失败图片,fallback 在 Drawable 在申请的 url/model 为 null 时展现。

Glide.with(this).load(url).centerCrop().placeholder(R.mipmap.ic_launcher).error(R.mipmap.login_icon).into(imageView);// 占位符
 Glide.with(this).load(url).fallback(R.mipmap.ic_launcher).into(imageView);// 如果申请的 url/model 为 null 的时候展现的图片(如果没有设置,还是展现 placeholder 的占位符)

3.asGif(),asBitmap()显示 gif 动画,asGif()判断是否是 gif 动画,asBitmap()能够加载动态 gif 图即 gif 图的第一帧

 Glide.with(this).load(url).asGif().into(imageView);// 显示 Gif 动画
 Glide.with(this).load(url).asBitmap().into(imageView);// 显示 Bitmap 图片
 

4. 设置动画
.crossFade():Glide 提供淡如淡出;
crossFade(int duration)// 设置动画工夫
crossFade(Animation animation, int duration)// 自定义动画和工夫
.dontAnimate()// 勾销动画
.animate(android.R.anim.slide_in_left):Android 零碎提供,从左到右滑出加载动画

  Glide.with(this).load(url).crossFade().into(imageView);
  Glide.with(this).load(url).animate(android.R.anim.slide_in_left).into(imageView);// 从左到右加载图片

5. 调整图片大小
单位是像素,裁剪你的图片大小。其实 Glide 曾经会主动依据你 ImageView 裁剪照片来放在缓存中了。然而不想适应 ImageView 大小的时候,能够调用这个办法.override()为 ImageView 指定大小

 Glide.with(this).load(url).override(100,100).animate(android.R.anim.slide_in_left).into(imageView);

6. 裁剪图片.fitCenter()和.CenterCrop()
当须要裁剪大小时,有个.centerCrop 办法,这个办法的裁剪会让你的 ImageView 四周不会留白,还有一个.fitCenter()办法,示意让你的 Image 齐全显示,尺寸不对时,四周会留白。

 Glide.with(this).load(url).fitCenter().animate(android.R.anim.slide_in_left).into(imageView);

7. 设置缩略图.thumbnail()

.thumbnail()办法的目标就是让用户先看到一个低解析度的图,点开后,再加载一个高解析度的图。

Glide.with(this).load(url).fitCenter().thumbnail(0.1f).animate(android.R.anim.slide_in_left).into(imageView);

一种更高级的缩略图加载形式:

当缩略图也须要通过网络加载全副解析度的时候。

private void loadImageThumbnailRequest() {DrawableRequestBuilder<String> thumbnailRequest = Glide.with(context.load(eatFoodyImages[2]);
    Glide.with(context).load(UsageExampleGifAndVideos.gifUrl).thumbnail(thumbnailRequest).into(imageView);
}

8. 设置图片显示成果(圆角、圆形、高斯含糊、蒙板、裁剪等等).bitmapTransform()

Glide.with(this).load(R.mipmap.ic_image_sample)
    // 含糊
    .bitmapTransform(new BlurTransformation(this))
    // 圆角
    .bitmapTransform(new RoundedCornersTransformation(this, 24, 0, RoundedCornersTransformation.CornerType.ALL))
    // 遮蔽
    .bitmapTransform(new MaskTransformation(this, R.mipmap.ic_launcher))
    // 灰度
    .bitmapTransform(new GrayscaleTransformation(this))
    // 圆形
    .bitmapTransform(new CropCircleTransformation(this))
    .into(imageView);

除此之外还有实现诸如马赛克、明暗度等更多滤镜解决:

  • ToonFilterTransformation
  • SepiaFilterTransformation
  • ContrastFilterTransformation
  • InvertFilterTransformation
  • PixelationFilterTransformation
  • SketchFilterTransformation
  • SwirlFilterTransformation
  • BrightnessFilterTransformation
  • KuwaharaFilterTransformation
  • VignetteFilterTransformation

9.Gilde 的缓存
缓存是为了缩小或者杜绝多的网络申请。为了防止缓存,Glide 用了内存缓存和‘外存缓存机制’, 并且 提供了相应的办法,齐全封装,不须要解决细节。Glide 会主动缓存到内存,除非调用.skipMemoryCache(true)。只管调用了这个,Glide 还是会缓存到外存,还有一种情景,就是有一张图片,然而这张图变动十分快,这个时候可能并不想缓存到外存中,就应用.diskCacheStrategy(DiskCacheStrategy.NONE)。如果你两种都不须要,能够两个办法组合着一起应用。

  • DiskCacheStrategy.NONE 什么都不缓存
  • DiskCacheStrategy.SOURCE 仅仅只缓存原来的全分辨率的图像
  • DiskCacheStrategy.RESULT 仅仅缓存最终的图像,即升高分辨率后的(或者是转换后的)
  • DiskCacheStrategy.ALL 缓存所有版本的图像(默认行为)

     // 设置跳过内存缓存
     Glide.with(this).load(url).animate(android.R.anim.slide_in_left).skipMemoryCache(true).into(imageView);
     
    // 设置硬盘缓存没有
    Glide.with(this).load(url).animate(android.R.anim.slide_in_left).diskCacheStrategy(DiskCacheStrategy.NONE).into(imageView);

    10. 申请的优先级.priority()
    载图片必定也是有先后顺序,Glide 提供了.priority()这个办法,它接管以下几个参数:

  • Priority.LOW
  • Priority.NORMAL
  • Priority.HIGH
  • Priority.IMMEDIATE
Glide.with(this).load(url).animate(android.R.anim.slide_in_left).diskCacheStrategy(DiskCacheStrategy.NONE).priority(Priority.LOW).into(imageView);

11. 监听器配置.listener()

  @Override
    public void onClick(View v) {
        String url = "http://guolin.tech/book.png";
        Glide.with(this).load(url).animate(android.R.anim.slide_in_left).listener(mRequestListener).into(imageView);


    }
    private RequestListener<String, GlideDrawable> mRequestListener = new RequestListener<String, GlideDrawable>() {
        @Override
        public boolean onException(Exception e, String model, com.bumptech.glide.request.target.Target<GlideDrawable> target, boolean isFirstResource) {
            // 显示错误信息
            Log.w("TAG", "onException:", e);
            // 打印申请 URL
            Log.d("TAG", "onException:" + model);
            // 打印申请是否还在进行
            Log.d("TAG", "onException:" + target.getRequest().isRunning());
            return false;
        }

        @Override
        public boolean onResourceReady(GlideDrawable resource, String model, com.bumptech.glide.request.target.Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {return false;}


    };

}

这里的 onException 捕捉异样,如果返回 true 示意咱们本人解决掉了异样,false 示意交给 Glide 去解决,因为咱们定义了.error()那么就显示 error 外面的内容。

这里 onResourceReady 示意是否筹备资源显示,返回 true 示意用户本人曾经设置好资源,包含截取操作,动画操作之类的,筹备好显示。false 示意交给 Glide

如此批改后,就可能看到图片加载日志了,不便咱们调试

12. 替换掉自带的 HttpClient
导入须要替换的 HttpClient,能够抉择 Volley 也能够抉择 OkHttp,咱们应用 Okhttp,在 Module 的 build.gradle 文件中配置

implementation "com.github.bumptech.glide:okhttp3-integration:4.11.0"

13.Glide 4 应用
而 Glide 4 中引入了一个 RequestOptions 对象,将这一系列的 API 都挪动到了 RequestOptions 当中。这样做的益处是能够使咱们解脱简短的 Glide 加载语句,而且还能进行本人的 API 封装,因为 RequestOptions 是能够作为参数传入到办法中的。

RequestOptions options = new RequestOptions()
        .placeholder(R.drawable.ic_launcher_background)
        .error(R.drawable.error)
        .diskCacheStrategy(DiskCacheStrategy.NONE);
Glide.with(this)
     .load(url)
     .apply(options)
     .into(imageView);

14. 对于图片变换,最初咱们再来看一个十分优良的开源库,glide-transformations。它实现了很多通用的图片变换成果,如裁剪变换、色彩变换、含糊变换等等,使得咱们能够十分轻松地进行各种各样的图片变换
增加库

dependencies {implementation 'jp.wasabeef:glide-transformations:3.0.1'}

三:应用 Generated API

Generated API 是 Glide 4 中全新引入的一个性能,它的工作原理是应用注解处理器 (Annotation Processor) 来生成出一个 API,在 Application 模块中可应用该流式 API 一次性调用到 RequestBuilder,RequestOptions 和集成库中所有的选项。
Generated API 对于相熟 Glide 3 的敌人来说那是再简略不过了,基本上就是和 Glide 3 截然不同的用法,只不过须要把 Glide 关键字替换成 GlideApp 关键字,如下所示:

GlideApp.with(this)
        .load(url)
        .placeholder(R.drawable.loading)
        .error(R.drawable.error)
        .skipMemoryCache(true)
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .override(Target.SIZE_ORIGINAL)
        .circleCrop()
        .into(imageView);

不过,有可能你的 IDE 中会提醒找不到 GlideApp 这个类。这个类是通过编译时注解主动生成的,首先确保你的代码中有一个自定义的模块,并且给它加上了 @GlideModule 注解,也就是咱们在上一节所讲的内容。而后在 Android Studio 中点击菜单栏 Build -> Rebuild Project,GlideApp 这个类就会主动生成了。

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {

    @Override
    public boolean isManifestParsingEnabled() {return false;}

    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, Registry registry) {
        // 配置 glide 网络加载框架
        registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
    }

    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        builder.setDefaultRequestOptions(new RequestOptions().format(DecodeFormat.PREFER_ARGB_8888));
        if (BuildConfig.DEBUG) {builder.setLogLevel(Log.DEBUG);
        }
    }
}

能够看到,在 MyAppGlideModule 类当中,咱们重写了 applyOptions()和 registerComponents()办法,这两个办法别离就是用来更改 Glide 配置以及替换 Glide 组件的。

留神在 MyAppGlideModule 类在下面,咱们退出了一个 @GlideModule 的注解,这是 Gilde 4 和 Glide 3 最大的一个不同之处。在 Glide 3 中,咱们定义了自定义模块之后,还必须在 AndroidManifest.xml 文件中去注册它能力失效,而在 Glide 4 中是不须要的,因为 @GlideModule 这个注解曾经可能让 Glide 辨认到这个自定义模块了
四:自定义本人的扩大类
定制本人的 API 须要借助 @GlideExtension 和 @GlideOption 这两个注解。创立一个咱们自定义的扩大类,代码如下所示:

@GlideExtension
public class MyGlideExtension {private MyGlideExtension() { }

    @GlideOption
    @NonNull
    public static BaseRequestOptions<?> roundCorner(@NonNull BaseRequestOptions<?> options) {return options.transform(new RoundedCorners(SizeUtils.dp2px(5)));
    }

}

这里咱们定义了一个 MyGlideExtension 类,并且给加上了一个 @GlideExtension 注解,而后要将这个类的构造函数申明成 private,这都是必须要求的写法。

接下来就能够开始自定义 API 了,这里咱们定义了一个 cacheSource()办法,示意只缓存原始图片,并给这个办法加上了 @GlideOption 注解。留神自定义 API 的办法都必须是静态方法,而且第一个参数必须是 RequestOptions,前面你能够退出任意多个你想自定义的参数

GlideApp.with(this)
        .load(url)
        .cacheSource()
        .into(imageView);

五:Glide 4 应用增加依赖

    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
    implementation "com.github.bumptech.glide:okhttp3-integration:4.11.0"

应用:

  Glide.with(this).load(R.mipmap.login_icon).placeholder(R.mipmap.ic_launcher).into(imageView);
  
  // 或者应用
  RequestOptions options=new RequestOptions().placeholder(R.mipmap.ic_launcher);//questOptions 容许你一次指定一系列的选项,而后对多个加载重用它们
        Glide.with(this).load(R.mipmap.login_icon).apply(options).into(imageView);
        // 这样抽取进去能够屡次加载

自定义模块 @GlideMoudule,这样的话就能创立一个自定模块类
咱们重写了 applyOptions()和 registerComponents()办法,这两个办法别离就是用来更改 Glide 配置以及替换 Glide 组件的。

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {

    @Override
    public boolean isManifestParsingEnabled() {return false;}

    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, Registry registry) {
        // 配置 glide 网络加载框架
        registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
    }

    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        builder.setDefaultRequestOptions(new RequestOptions().format(DecodeFormat.PREFER_ARGB_8888));
        if (BuildConfig.DEBUG) {builder.setLogLevel(Log.DEBUG);
        }
    }
}

而后 Bulid–>Rebulid Project

// 这样的话就是吧 Glide 换成 GlideApp
 GlideApp.with(this).load(R.mipmap.login_icon).into(imageView);

自定义 Api:mini()办法

@GlideExtension
public class MyGlideExtension {private MyGlideExtension() { }
    @GlideOption
    @NonNull
    public static BaseRequestOptions<?> mini(@NonNull BaseRequestOptions<?> options, int size) {return options.fitCenter().override(size);
    }
    // 这是一个 Api 扩大,应用居中裁剪和调整图片 size 大小尺寸
}

而后 Bulid–>Rebulid Project
最初调用

 GlideApp.with(this).load(R.mipmap.login_icon).mini(66).into(imageView);

Glide 相干博客:https://guolin.blog.csdn.net/…

END: 我开始在人世间漂流,抉择过大大小小的幻想

退出移动版