【发布时间】:2020-12-24 19:30:05
【问题描述】:
在安卓应用中使用 Glide v4。用例是有一个活动在后台堆栈中有一些片段。 每个 Fragment 将从远程加载一到十个以下的图像。
具有将图像加载到 ImageView 的 kotlin 扩展:
fun ImageView.loadImg(
imageUrl: String,
diskCacheStrategy: DiskCacheStrategy = DiskCacheStrategy.AUTOMATIC,
skipMemoryCache: Boolean = true,
roundingRadius: Int = 0,
target: Target<Drawable>? = null,
requestOptions: RequestOptions = RequestOptions(),
decodeFormat: DecodeFormat = DecodeFormat.PREFER_RGB_565
) {
requestOptions
.diskCacheStrategy(diskCacheStrategy)
.format(decodeFormat)
.apply {
if (roundingRadius > 0) {
transform(CenterCrop(), RoundedCorners(roundingRadius))
}
}
Glide.with(this.context)
.load(imageUrl)
.apply(requestOptions)
.skipMemoryCache(skipMemoryCache)
.apply {
if (target == null) {
into(this@loadImg)
} else {
into(target)
}
}
}
片段中的典型调用如下:
imageView.loadImg(
imageUrl = imageUrl,
roundingRadius = imageRoundingRadius,
target = object : CustomViewTarget<ImageView, Drawable>(imageView) {
override fun onLoadFailed(errorDrawable: Drawable?) {
imageView.setImageDrawable(null)
visibility = View.GONE
}
override fun onResourceCleared(placeholder: Drawable?) {
imageView.setImageDrawable(null)
visibility = View.GONE
}
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
imageView.setImageDrawable(resource)
visibility = View.VISIBLE
}
}
)
问题是每当一个片段被放入视图并添加到后台堆栈时,分析器中的图形内存显示增加了 50 毫克。除了片段中的图像之外,没有太多其他数据。如果注释掉加载图片好像减少了很多。
不确定这里的代码 loadImage() 是否正确?注意到它在 Glide.with(this.context) 中使用 ImageView 的上下文,也就是 Activity。这是个问题吗? Glide.with(this.context) 和 Glide.with(theFragment) 有什么区别? 什么时候清除Target最好:Glide.with(theFragment).clear(theTarget)?
注意到有一个 CustomTarget(),如果它可以占用图像大小,使用它是否有助于减少内存使用?
目标代码如下:Target<Bitmap>
fun ImageView.loadImgAsBitmap(
imageUrl: String,
diskCacheStrategy: DiskCacheStrategy = DiskCacheStrategy.AUTOMATIC,
skipMemoryCache: Boolean = true,
roundingRadius: Int = 0,
target: Target<Bitmap>? = null,
requestOptions: RequestOptions = RequestOptions(),
decodeFormat: DecodeFormat = DecodeFormat.PREFER_RGB_565
) {
requestOptions
.diskCacheStrategy(diskCacheStrategy)
.format(decodeFormat)
.apply {
if (roundingRadius > 0) {
transform(CenterCrop(), RoundedCorners(roundingRadius))
}
}
Glide.with(this.context)
.asBitmap()
.load(imageUrl)
.apply(requestOptions)
.skipMemoryCache(skipMemoryCache)
.apply {
if (target == null) {
into(this@loadImgAsBitmap)
} else {
into(target)
}
}
}
和用法是:
imageView.loadImgAsBitmap(imageUrl,
target = object : CustomTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
if (resource.height < IMAGE_MIN_SIZE) {// it could check the bitmap size and make use of it
imageView.visibility = View.GONE
textView.visibility = View.VISIBLE
} else {
imageView.setImageBitmap(resource)
}
}
override fun onLoadCleared(placeholder: Drawable?) {
imageView.setImageDrawable(null)
}
})
这个至少提供位图大小更好,以便 UI 可以使用它。
问题是使用CustomTarget<Bitmap>() 比Target<Drawable> 更能减少内存使用吗?
如何指定图片大小来替换默认的Target.SIZE_ORIGINA,即is very memory inefficient?
【问题讨论】:
标签: out-of-memory android-glide