Android 在毕加索中应用变换时,原始图像的缓存不被重用

Android 在毕加索中应用变换时,原始图像的缓存不被重用,android,picasso,image-caching,Android,Picasso,Image Caching,我试图使用毕加索在原始位图和转换位图之间切换。 问题是第一次加载原始图像时,它似乎被缓存,但当我加载转换后的图像时,它似乎再次重新加载图像,而不使用缓存。相同的url用于获取图像。它只在原始和转换的第一次发生,然后使用缓存 我的期望是毕加索应该自动重用兑现的原始图像来应用转换并毫不延迟地重新加载它。也许我错过了什么 这是图像加载的代码 private fun loadOriginalImage(i: Product, productImage: ImageView) { 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)
}

毕加索版本
实现'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)

这样,我的占位符就是原始图像,它使转换平滑,并消除了缓存所有转换图像的潜在开销。

在我的情况下,我不会自己操作缓存。所以我想毕加索应该在引擎盖下使用lru缓存。告诉我缓存未被使用的是,当加载位图时,我第一次看到占位符,然后没有看到占位符,这表明缓存被重用。我将尝试您的建议啊,在这种情况下,您可能会在首次加载占位符时看到占位符,因为对原始图像应用转换需要一些时间(即使它以前已缓存)。在缓存已经包含转换后的图像后,毕加索跳过转换步骤,立即将图像加载到视图中(有点道理),您认为有解决此问题的方法吗?我的期望是,它能以比现在快1-2秒的速度发生”\_(ツ)_/''取决于特定的使用情况。检查原始图像的大小,可能它对移动设备来说太大了,可以缩小(图像越小-转换时间越短),将回调添加到原始图像的第一次加载中,这样它就可以开始转换,并在转换后立即将修改后的图像放入缓存中。回调的想法可能是解决方案。那么它在代码方面会如何?我会检查大小,但我很确定它是移动适应的。