1 学习大纲
muyangmin.github.io/glide-docs-…
2 Glide加载
2.1 Glide加载问题
- 加载Uri
Uri.parse("res://" + context.packageName + "/" + drawableResId)
2.2 Glide缓存策略
| 缓存策略 | 英文说明 | 中文说明 |
|---|---|---|
| DiskCacheStrategy ALL | Caches remote data with both DATA and RESOURCE, and local data with RESOURCE only. | 使用data和RESOURCE缓存远程数据,仅使用RESOURCE缓存本地数据。 |
| DiskCacheStrategy NONE | Saves no data to cache. | 不缓存 |
| DiskCacheStrategy DATA | Writes retrieved data directly to the disk cache before it's decoded. | 在解码之前将检索到的数据直接写入磁盘缓存。 |
| DiskCacheStrategy RESOURCE | Writes resources to disk after they've been decoded | 将资源解码后写入磁盘 |
| DiskCacheStrategy AUTOMATIC | Tries to intelligently choose a strategy based on the data source of the com.bumptech.glide.load.data.DataFetcher and the EncodeStrategy of the com.bumptech.glide.load.ResourceEncoder (if an com.bumptech.glide.load.ResourceEncoder is available). | 智能选择策略 |
| boolean isResourceCacheable | Returns true if this request should cache the final transformed resource. | 该请求缓存最终转换的资源,则返回true |
| boolean decodeCachedResource | Returns true if this request should attempt to decode cached resource data. | 该请求尝试解码缓存的资源数据,则返回true |
| boolean decodeCachedData | Returns true if this request should attempt to decode cached source data. | 该请求尝试解码缓存的源数据,则返回true |
2.3 Glide 适配广色域
fun getRequestOptionsWithColorSpace(options: RequestOptions): RequestOptions {
if (isSupportWCG()) {
options.set(Downsampler.PREFERRED_COLOR_SPACE, PreferredColorSpace.DISPLAY_P3)
} else {
options.set(Downsampler.PREFERRED_COLOR_SPACE, PreferredColorSpace.SRGB)
}
return options
}
使用BitmapFactory
在 API 26 中,我们为 BitmapFactory.Option添加了inPreferredColorSpace,允许您为已解码的 Bitmap 文件指定目标色彩空间。假设您现在想要解码一个文件,那么您可以用下面的代码进行色彩管理
final BitmapFactory.Options options = new BitmapFactory.Options();
// Decode this file to sRGB color space.
options.inPreferredColorSpace = ColorSpace.get(Named.SRGB);
Bitmap bitmap = BitmapFactory.decodeFile(FILE_PATH, options);
使用ImageDecoder
在以下示例代码中,我们使用 ImageDecoder#decodeBitmap API 将图片转换为 sRGB 位图。
ImageDecoder.Source source =
ImageDecoder.createSource(FILE_PATH);
try {
bitmap = ImageDecoder.decodeBitmap(source,
new ImageDecoder.OnHeaderDecodedListener() {
@Override
public void onHeaderDecoded(ImageDecoder decoder,
ImageDecoder.ImageInfo info,
ImageDecoder.Source source) {
decoder.setTargetColorSpace(ColorSpace.get(Named.SRGB));
}
});
} catch (IOException e) {
// handle exception.
}
2.4 预加载
//提前加载
fun preloadIcon(context: Context?, iconUrl: String) {
context?.let {
Glide.with(it)
.load(iconUrl)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.preload()
}
}
2.5 加载的对象是View,但不是ImageView
//加载view
val cardViewTarget = ShadowCardViewTarget(iconView)
Glide.with(this.context)
.load(appIconUrl)
.placeholder(R.drawable.snack_bar_ic_icon_default)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(cardViewTarget)
class ShadowCardViewTarget(
private val customView: ShadowCardView
) : CustomViewTarget<COUIShadowCardView, Drawable>(customView) {
override fun onLoadFailed(errorDrawable: Drawable?) {
}
override fun onResourceCleared(placeholder: Drawable?) {
}
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
customView.background = resource
}
}
2.7 加载Bitmap
//加载Bitmap
Glide.with(it).asBitmap().load(imageUrl)
.into(object : CustomTarget<Bitmap?>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap?>?) {
setBackground(resource)
}
override fun onLoadCleared(placeholder: Drawable?) {
}
})
Glide加载遇到的缓存问题
解决方法可参考这两篇文章
3 Glide常见问题
3.1 Glide加载网络图片不显示
Glide在Android 9不再支持http协议,需将http换成https
【分析方法1】 单步调试,跟踪异常抛出的log如下
com.bumptech.glide.load.engine.GlideException: Failed to load resource
There was 1 root cause:
java.net.SocketTimeoutException(failed to connect to ******.com/***** (port 443) from /**.***.***.** (port 42792) after 10000ms: isConnected failed: ETIMEDOUT (Connection timed out))
call GlideException#logRootCauses(String) for more detail
【原因分析1】 确认pb是否有返回,无返回的话,说明是服务端的问题
【解决方法1】 1.确认pb是否有返回
Failed to load resource
There was 1 root cause:
java.net.SocketTimeoutException(timeout h2 stream:read)
call GlideException#logRootCauses(String) for more detail
【分析方法2】
打印异常时,通过GlideException#logRootCauses打印原因
3.2 Glide加载网络图片不显示
【分析方法】
- 添加如下监听
- 在onLoadFailed中增加断点,进行单步调试
.listener(object : RequestListener<Bitmap> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Bitmap>?,
isFirstResource: Boolean
): Boolean {
Log.i(tag, "onLoadFailed")
e?.printStackTrace()
return false
}
override fun onResourceReady(
resource: Bitmap?,
model: Any?,
target: Target<Bitmap>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
Log.i(tag, "onResourceReady")
return false
}
})
.into(object : BitmapThumbnailImageViewTarget(imageView) {
override fun onLoadStarted(placeholder: Drawable?) {
super.onLoadStarted(placeholder)
Log.i(tag, "onLoadStarted")
}
override fun onLoadFailed(errorDrawable: Drawable?) {
// 此处增加断点,进行单步调试,查看异常log
super.onLoadFailed(errorDrawable)
Log.i(tag, "onLoadFailed")
}
override fun onResourceReady(
resource: Bitmap,
transition: Transition<in Bitmap>?
) {
super.onResourceReady(resource, transition)
Log.i(tag, "onResourceReady transition")
}
override fun onLoadCleared(placeholder: Drawable?) {
super.onLoadCleared(placeholder)
Log.i(tag, "onLoadCleared transition")
}
})
【原因分析】
- 从上述断点调试的log中,可以看到如下exception,原因为:秘钥链验证失败,导致加载资源失败。
- 此错误来自 SSL Handshake 库,因为 SDK 正在尝试向sdk.split.io调用 GET http 请求。一个可能的根本原因是设备时间与当前时间不一致。
com.bumptech.glide.load.engine.GlideException: Failed to load resource
There was 1 root cause:
com.bumptech.glide.load.HttpException(****-***.storage.wanyol.com==>Exception:Chain validation failed, status code: 400)
call GlideException#logRootCauses(String) for more detail
查看Glide源码可知,该错误为:
private void notifyFailed() {
setNotifiedOrThrow();
GlideException e = new GlideException("Failed to load resource", new ArrayList<>(throwables));
callback.onLoadFailed(e);
onLoadFailed();
}
【解决方案】
1、调整手机的时间为当前正确时间,查看上述现象解决
3.3 GLide加载大图优化
针对高清图加载慢的问题,可以先加载缩略图,再加载高清图
private fun loadThumbnailAndFullImage(imageView: ImageView) {
val thumbnailUrl = "https://example.com/thumbnail.jpg" // 替换为你的缩略图URL
val fullImageUrl = "https://example.com/full_image.jpg" // 替换为你的高清图URL
Glide.with(this)
.load(fullImageUrl)
.thumbnail(Glide.with(this).load(thumbnailUrl))
.into(imageView)
}