安卓基础开发库,让开发简单点。

DevRing & Demo地址https://github.com/LJYcoder/DevRing

学习/参考地址:

https://blog.csdn.net/column/details/15318.html

https://blog.csdn.net/u013005791/article/details/74532091

https://www.jianshu.com/p/325bd2f56ca7

前言

距离上次发新篇已经有五个月了,趁现在无业游民一个,赶紧写多几篇完善一下这个系列。


今天给大家带来的是图片加载框架Glide的使用介绍。这里首推郭神的Glide系列教程,配合了源码讲解得很详细清晰。下面算是对学习实践后做的一个归纳总结,不涉及源码分析,仅涉及相关用法。

Glide相比起Fresco要轻量很多,api调用起来也很简洁,对图片加载要求不是很高的话建议使用Glide。

关于Fresco与Glide的对比可以参考这里

本文介绍涉及的Glide版本为4.x

介绍

下面还是和以前一样,分几个模块来进行介绍:配置、加载图片、获取Bitmap、下载图片、Generated API、混淆。

1. 配置

1.1 添加依赖

compile 'com.github.bumptech.glide:glide:4.4.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.4.0' //注解处理器

1.2 自定义模块

自定义模块包括:修改默认配置(比如缓存) 和 替换组件(比如网络组件)。

实现方式是通过继承AppGlideModule类并重写相关方法。

记得在该类上方加上@GlideModule注解以便Glide识别。如下:

@GlideModule
public class GlideConfigModule extends AppGlideModule {
@Override
public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
//修改默认配置,如缓存配置
}
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
//替换组件,如网络请求组件
}

}

1.2.1 修改缓存配置

在applyOption方法中对磁盘缓存和内存缓存进行相关配置

@Override
public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
//磁盘缓存配置(默认缓存大小250M,默认保存在内部存储中)
//设置磁盘缓存保存在外部存储,且指定缓存大小
builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, diskCacheSize);
//设置磁盘缓存保存在自己指定的目录下,且指定缓存大小
builder.setDiskCache(new DiskLruCacheFactory(new DiskLruCacheFactory.CacheDirectoryGetter() {
@Override
public File getCacheDirectory() {
return diskCacheFolder;
}
}, diskCacheSize);
//内存缓存配置(不建议配置,Glide会自动根据手机配置进行分配)
//设置内存缓存大小
builder.setMemoryCache(new LruResourceCache(memoryCacheSize));
//设置Bitmap池大小
builder.setBitmapPool(new LruBitmapPool(bitmapPoolSize));
}

1.2.2 替换组件

比如替换网络组件为okhttp。

添加相关依赖即可。

compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.github.bumptech.glide:okhttp3-integration:4.3.1'

查看代码后可以发现,它内部实现其实就是在registerComponents方法中进行了组件替换.

@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
}

当然还有很多组件可以替换,但一般没这种需求。

//Glide中默认组件
register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());
register(File.class, InputStream.class, new StreamFileLoader.Factory());
register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
register(int.class, InputStream.class, new StreamResourceLoader.Factory());
register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());
register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());
register(String.class, InputStream.class, new StreamStringLoader.Factory());
register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());
...

1.2.3 注意

一个项目(包含主项目与依赖库)中只能存在一个继承AppGlideModule的自定义模块,如果有多个,则会报com.android.dex.DexException: Multiple dex files define Lcom/bumptech/glide/GeneratedAppGlideModuleImpl异常。

但是允许有多个继承LibraryGlideModule的自定义模块(用于重写registerComponents进行组件替换)。

2. 加载图片

2.1 常用操作

2.1.1 加载图片到ImageView

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

其中,
with() 方法的参数可以是Activity、Fragment等。将用于图片加载的生命周期,比如传入的是activity,那么在activity销毁时将对相关图片资源进行回收。

load() 方法的参数可以为String、Uri、File、资源ID等。

into() 方法的参数可以是ImageView,Target、图片的宽高。

2.1.2 加载图片到ImageView,并指定占位图

RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(loadingResId) //设置“加载中”状态时显示的图片
.error(errorResId); //设置“加载失败”状态时显示的图片
Glide.with(context)
.load(url)
.apply(requestOptions)
.into(imageView);

2.1.3 加载图片到ImageView,并指定缓存策略

RequestOptions requestOptions = new RequestOptions();
requestOptions.skipMemoryCache(true) //不加入内存缓存,默认会加入
.diskCacheStrategy(DiskCacheStrategy.NONE); //不加入磁盘缓存
Glide.with(context)
.load(url)
.apply(requestOptions)
.into(imageView);

磁盘缓存策略有以下几种:

DiskCacheStrategy.NONE: 表示不缓存任何内容。

DiskCacheStrategy.DATA: 表示只缓存原始图片。

DiskCacheStrategy.RESOURCE: 表示只缓存转换过后的图片。

DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片。

DiskCacheStrategy.AUTOMATIC: 表示让Glide根据图片资源智能地选择使用哪一种缓存策略(默认选项)。

另外再补充两点:

  1. 网络图片缓存是根据url地址进行存储的,对于“同一张图片但其url地址不同(可变动)”的情况,则无法起到缓存作用。这个时候可以通过自定义Url来应对这种情况,具体方案请参考这里的“高级技巧”小节。
  2. 清空缓存数据
//清空内存缓存,要求在主线程中执行
Glide.get(mContext).clearMemory();
//清空磁盘缓存,要求在后台线程中执行
Glide.get(mContext).clearDiskCache();

2.1.4 加载图片到ImageView,并指定图片大小

RequestOptions requestOptions = new RequestOptions();
requestOptions.override(300, 200); //指定大小为300*200,无视imageView大小
//requestOptions.override(Target.SIZE_ORIGINAL); //指定大小为图片原始大小,有更高OOM风险
Glide.with(context)
.load(url)
.apply(requestOptions)
.into(imageView);

2.1.5 加载图片到ImageView,并配置过渡动画

Glide.with(context)
.load(url)
.transition(DrawableTransitionOptions.withCrossFade(600))//适用于Drawable,过渡动画持续600ms
// .transition(BitmapTransitionOptions.withCrossFade(600))//适用于Bitmap,过渡动画持续600ms
// .transition(GenericTransitionOptions.with(animationId))//适用于自定义过渡效果,传入animationId
.into(imageView);

2.1.6 加载图片到ImageView,并加入图片变换

确保已添加图片变换库依赖:

 compile 'jp.wasabeef:glide-transformations:3.1.1@aar'//图片转换工具

应用单个变换

RequestOptions requestOptions = new RequestOptions();
//加入圆角变换
requestOptions.transform(new RoundedCornersTransformation(radius, margin));
//加入模糊变换
//requestOptions.transform(new BlurTransformation(blurRadius));
//加入灰白变换
//requestOptions.transform(new GrayscaleTransformation());
....
Glide.with(context)
.load(url)
.apply(requestOptions)
.into(imageView);

同时应用多个变换

List<Transformation> list = new ArrayList<>();
list.add(new RoundedCornersTransformation(radius, margin));
list.add(new BlurTransformation(blurRadius));
list.add(new GrayscaleTransformation());
MultiTransformation multiTransformation = new MultiTransformation(list);
RequestOptions requestOptions = new RequestOptions();
//同时应用圆角、模糊、灰白的变换效果
requestOptions.transform(multiTransformation);
Glide.with(context)
.load(url)
.apply(requestOptions)
.into(imageView);

更多变换效果请查看https://github.com/wasabeef/glide-transformations

另外,可以通过dontTransform()禁用图片变换。

RequestOptions requestOptions = new RequestOptions();
requestOptions.dontTransform();
Glide.with(context)
.load(url)
.apply(requestOptions)
.into(imageView);

2.2 预加载

有时为了更流畅的体验,可以使用预加载功能先把图片准备好,等到要显示时加载速度就很快了。

Glide.with(context)
.load(url)
.preload();

2.3 监听加载结果

如果你需要知道加载的结果,可以使用listener()进行监听。

Glide.with(context)
.load(url)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
//加载失败
return false;
}
    <span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onResourceReady</span><span class="hljs-params">(Drawable resource, Object model, Target&lt;Drawable&gt; target, DataSource dataSource, <span class="hljs-keyword">boolean</span> isFirstResource)</span> </span>{
<span class="hljs-comment">//加载成功,resource为加载到的图片</span>
<span class="hljs-comment">//如果return true,则不会再回调Target的onResourceReady(也就是不再往下传递),imageView也就不会显示加载到的图片了。</span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
}
}).into(imageView);

3. 获取Bitmap

有些时候,我们需要拿到加载回来的Bitmap对象,下面介绍两种实现方式。

3.1 通过listener()实现

Glide.with(context)
.asBitmap() //指定格式为Bitmap
.load(url)
.listener(new RequestListener<Bitmap>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
//加载失败
return false;
} @Overridepublic boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
//加载成功,resource为加载到的bitmap
return false;
}
})
.into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);//加载原图大小

3.2 通过SimpleTarget实现

Glide.with(context)
.asBitmap()
.load(url)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
//加载成功,resource为加载到的bitmap
}
});
//这种实现方式就无法监听到加载失败的结果

4. 下载图片

使用submit()方法实现图片的下载。

下载图片并保存到指定的文件中:

public void downLoadImage(final Context context, final String url, final File targetFile, final ImageListener<File> imageListener) {
if (cacheThreadPool == null) {
cacheThreadPool = Executors.newCachedThreadPool();
}
cacheThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
File sourceFile = Glide.with(context).asFile().load(url).submit().get();
if (FileUtil.copyFile(sourceFile, targetFile) && imageListener != null) {
imageListener.onSuccess(targetFile);//通过回调传递File,回调在后台线程
}
} catch (Exception exception) {
if (imageListener != null) {
imageListener.onFail(exception);//回调在后台线程
}
}
}
});
}

5. Generated API

Glide4.x之后引入的新功能。

5.1 作用1:可以继续像3.x那样链式调用加载

前提是项目中需要有一个自定义模块(参照1.2节)

然后便可以像3.x那样加载图片

GlideApp.with(context)
.load(url)
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.override(300,300)
.transition(DrawableTransitionOptions.withCrossFade(600))
.tranform(new GrayscaleTransformation())
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
....
.into(imageView);

5.2 作用2:定制属于你的API

假设现在需要每次加载图片都开启过渡动画效果,可以每次加载时加入.transition(DrawableTransitionOptions.withCrossFade(duration))来实现,但每次都写这么长的代码难免不太方便,这时可以通过定制API来实现。

自定义一个类,用于定制API。

要求:

1.类上方加入@GlideExtension注解。

2.自定义的方法上方加入@GlideOption注解。

3.自定义的方法须为静态方法,且第一个参数必须是RequestOptions,后面可以加入任意多个你想自定义的参数。

@GlideExtension
public class MyGlideExtension {
private MyGlideExtension() {
}
@GlideOption
public static void useTransition(RequestOptions options) {
options.transition(DrawableTransitionOptions.withCrossFade(600))
}}

ReBuild项目后,便可如下调用:

GlideApp.with(context)
.load(url)
.useTransition() //使用过渡动画效果
.into(imageView);

6. 混淆

在proguard-rules.pro文件中添加以下内容进行混淆配置

#glide开始
-keep public class * implements com.bumptech.glide.module.AppGlideModule
-keep public class * implements com.bumptech.glide.module.LibraryGlideModule
-keep class com.bumptech.glide.** { *; }
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
#glide结束

快速上手的Glide4.x教程的更多相关文章

  1. 快速上手Ubuntu之安装篇——安装win7,Ubuntu16.04双系统【转】

    本文转载自:http://blog.csdn.net/qq_28205153/article/details/52203512 Linux可以说是开发者的系统,对于开发者来说,Linux发行版不仅为我 ...

  2. NHibernate3快速上手教程FluentNHibernate配置与DBHelper

    很多学习NHibernate的新手很容易卡在配置文件这一关,正所谓万事开头难,上手后再配合官方文档就比较容易了. 网上关于配置文件的资料非常多,但由于版本的问题,许多老的教程中都没有明确指出类库的版本 ...

  3. 新浪SAE快速上手教程

     新浪SAE快速上手教程[1]如何免费开通新浪云 2014-07-18 > 新浪SAE快速上手教程[2]如何创建.删除应用 2014-07-24 > 新浪SAE快速上手教程[3]如何上传应 ...

  4. Airtest 快速上手教程

    一.Airtest 简介: AirtestIDE 是一个跨平台的UI自动化测试编辑器,适用于游戏和App. 自动化脚本录制.一键回放.报告查看,轻而易举实现自动化测试流程 支持基于图像识别的 Airt ...

  5. 【RL-TCPnet网络教程】第3章 初学RL-TCPnet的准备工作及其快速上手

    第3章       初学RL-TCPnet的准备工作及其快速上手 俗话说万事开头难,学习一门新的知识,难的往往不是知识本身,而是如何快速上手,需要什么资料和开发环境.一旦上手后,深入的学习就相对容易些 ...

  6. EntityFramework 5.0 CodeFirst 教程01-搭建环境和快速上手

    ----------------------------目录------------------------------ EntityFramework 5.0 CodeFirst 教程03-数据结构 ...

  7. 想要快速上手 Spring Boot?看这些教程就足够了!| 码云周刊第 81 期

    原文:https://blog.gitee.com/2018/08/19/weekly-81/ 想要快速上手 Spring Boot?看这些教程就足够了!| 码云周刊第 81 期 码云周刊 | 201 ...

  8. NHibernate3快速上手教程FluentNHibernate配置与DBHelper(已过期,有更好的)

    很多学习NHibernate的新手很容易卡在配置文件这一关,正所谓万事开头难,上手后再配合官方文档就比较容易了. 网上关于配置文件的资料非常多,但由于版本的问题,许多老的教程中都没有明确指出类库的版本 ...

  9. smarty半小时快速上手入门教程

    http://www.jb51.net/article/56754.htm http://www.yiibai.com/smarty/smarty_functions.html http://www. ...

随机推荐

  1. Linux系统安全

    简单优化: 1.删除不必要的软件包(如postfix等) yum remove -y postfix 安装管理:1.口令 1.1至少8个字符,大小写.特殊字符和数字组合,定期更改 1.2口令长度可以编 ...

  2. Linux上部署Springboot相关命令

    ps -ef|grep java 看有关java的进程 ps -ef是显示所有进程信息 后面那个grep是匹配的意思 kill -9 123123 213231 后面两个数字是两个进程的进程号pid, ...

  3. STM8硬件设计注意事项

    1.中断 STM8的外部中断和STM32不一样,每个端口PX只有1个中断 2.ADC 1)Additional AIN12 analog input is not selectable in ADC ...

  4. Nginx实现rewrite重写

    目录 Rewrite基本概述 Rewrite标记Flag Rewrite规则实践 Rewrite场景示例 Rewrite规则补充 rewrite优先级实战 Rewrite基本概述 什么是rewrite ...

  5. [web设计]带有方向感应的hover effect

    See the Pen bdxLQa by jeremylee (@lijie33402) on CodePen. codepen不知道怎么嵌入到cnblogs..待编辑 参考资料 参考博客

  6. 第11篇Kubernetes部署微服务电商平台

        kubernetes部署sock-shop微服务电商平台: 准备条件   确保kubernetes可以访问:reg.yunwei.edu镜像库   需要准备镜像:       部署微服务   ...

  7. egg 连接mysql 在mysql 插入数据

    1.配置mysql exports.mysql = { enable: true, package: 'egg-mysql' }; 'use strict'; module.exports = app ...

  8. cocos2D-X 显示中文

    { 将所在的cpp文件改为utf-8 无签名格式再编译 //但,治标不治本 }

  9. JavaScript面向对象小抄集

    前言 本文旨在记录JavaScript中面向对象的基础知识 搞明白JavaScript中的面向对象 一切都是对象 JavaScript中,除了基本类型外,其它类型都是对象类型 所谓对象就是若干属性的集 ...

  10. mysql添加索引和sql分析

    mysql索引操作 查看索引 show indexes from students; #students为表名 mysql添加索引命令 创建索引 .PRIMARY KEY(主键索引) mysql> ...