在 Picasso 中应用变换时,不会重复使用原始图像的缓存



我正在尝试使用毕加索在原始位图和转换后的位图之间切换。 问题是第一次加载原始图像时,它似乎被缓存了,但是当我加载转换后的图像时,它似乎再次重新加载图像并且不使用缓存。相同的 URL 用于获取图像。它只发生在原始和转换的第一次,然后使用缓存。

我希望毕加索应该自动重复使用兑现的原始图像来应用变换并立即重新加载它。也许我错过了什么。

这是图像加载的代码。

private fun loadOriginalImage(i: Product, productImage: ImageView) {
Picasso.get().load(getProductUrl(i.id)).placeholder(R.color.light_grey)
.error(R.color.light_grey).fit().centerCrop().into(productImage)
}

private fun loadGreyedImage(i: Product, productImage: ImageView) {
Picasso.get().load(getProductUrl(i.id)).placeholder(R.color.light_grey)
.error(R.color.light_grey).fit().centerCrop().transform(GrayScaleTransform()).into(productImage)
}

毕加索版本implementation 'com.squareup.picasso:picasso:2.71828'

是内存缓存还是磁盘缓存? 您如何验证缓存确实未被使用?

这里有一些选项(考虑到MemoryPolicy和NetworkPolicy没有被修改,你没有替换标准的okHTTP3客户端):

  • 图像在这两个调用之间被推出内存缓存(缓存太小,无效调用等)
  • 磁盘缓存由HTTP客户端控制,与毕加索无关,因此不正确设置http标头可能会导致这种情况(但在这种情况下,原始图像应该已经从内存缓存中删除)

打开指示器和日志记录可以提供有关正在发生的事情的更多信息:

Picasso  
.with(context)
.setIndicatorsEnabled(true)
.setLoggingEnabled(true)

此外,如果只能执行这两个调用,则可以执行它们并从内存缓存中获取快照数据以检查其大小,命中和未命中等:

StatsSnapshot stats = Picasso.with(context).getSnapshot();  
Log.d("stats", stats.toString());  

这可能会提供更多的调试信息来考虑,例如,是否恰好有两个对缓存的调用,是否有遗漏等

编辑:key() 函数是否在您的转换中正确实现?

启用日志后,我验证了原始图像确实被缓存,并且正如@Sputnik所建议的那样,问题似乎是由于从原始图像缓存创建转换后的位图的延迟引起的。

但是预缓存转换后的图像的解决方案并不是最好的解决方案。首先,有相当多的图像,只有当用户点击回收器中的图像时才需要灰度图像。它可能永远不会发生,但我们已经缓存了两倍大小的图像以防万一。

因此,在与毕加索一起玩并记录之后,对我有用的解决方案是使用原始图像作为占位符。

所以而不是

Picasso.get().load(getProductUrl(i.id)).placeholder(R.color.light_grey)
.error(R.color.light_grey).fit().centerCrop().transform(GrayScaleTransform()).into(productImage)

我做到了

Picasso.get().load(getProductUrl(i.id)).placeholder(productImage.drawable)
.error(R.color.light_grey).fit().centerCrop().transform(GrayScaleTransform()).into(productImage)

这样,我的占位符是原始图像,它使过渡顺利进行,并通过缓存所有转换后的图像来消除潜在的开销。

最新更新