【问题标题】:Picasso Image downloaded again for an ImageView with different dimensions?为不同尺寸的 ImageView 再次下载毕加索图像?
【发布时间】:2016-05-11 10:06:36
【问题描述】:

我在我的应用程序中使用 Picasso 来有效地加载图像并且做得最好。问题是,目前如果我使用相同的 url 多次调用 Picasso.with(),但是每次都有一个图像视图不同的尺寸,图像再次下载。在Glide我们有.diskCacheStrategy()DiskCacheStrategy.SOURCE的方法来解决问题。毕加索有没有其他方法?

this 查询中,我们将获得 Glid 的解决方案,但不是 Picasso。如何在不重新下载不同尺寸的 ImageView 的情况下重用图像。

这是我正在使用的代码

Picasso.with(context)
                .load(URI)
                .placeholder(R.drawable.ic_profile_thumb)
                .resize(180, 180).centerInside()
                .into(viewHolder.imgThumbnail);

【问题讨论】:

  • 看看这个答案stackoverflow.com/a/28964219/1384010。希望这对你有帮助!!
  • 您能粘贴您与毕加索相关的代码吗?您是否使用调整大小选项?
  • @Scotti 请检查我的代码。我正在使用调整大小操作。
  • @Stella:您是否检查了相关图像文件的 HTTP 标头?如果他们不允许缓存,那么 OkHttp 或 Volley 可能会再次下载它 - 他们应该这样做。

标签: java android picasso


【解决方案1】:

您可以使用来自同一供应商“SquareUp”的OkHttp
This answer 向您展示如何使用详细信息。

【讨论】:

  • 所以,如果我在 URL 保持不变但图像更新意味着我应该做些什么来克服这一点时使用缓存图像。我的意思是在glide 我们得到signature() 方法毕加索的任何替代方案?
  • 要么使用 OkHttp(如果项目中包含 Picasso 将在后台使用它),要么使用 HttpUrlConnection(如果不包含 OkHttp 且未定义其他内容,Picasso 将使用它作为后备) ) 必须定义缓存策略,并且可以通过 Picasso 定义而无需深入。主要问题/问题的范围对我来说不是很清楚,可能就像不使用 resize() 方法一样简单。
【解决方案2】:

Picasso 不会将图像缓存到磁盘,Picasso 只有内存缓存。磁盘缓存由网络库(OKhttp)完成。因此写入磁盘缓存的图像永远不会重新调整大小。

如果多次下载相同的 url 图片,您可能需要检查您的网络库。

如果您的项目正在使用 okhttp 库,那么 picasso 将自动将其用作默认下载器。如果您正在使用任何其他网络库,那么您必须编写自己的下载器并使用

进行设置
Picasso.Builder(context).downloader(customDownloader)

this link 可能会让事情变得清晰

【讨论】:

  • 你能用实际代码解释你的答案吗?我使用 volley 作为我的 n/w 库。
  • - Picasso 提供开箱即用的自动内存和磁盘缓存。看看我上面的回答。 - 如果您使用 resize() 方法,AFAIK 磁盘缓存中的图像会调整大小。
  • @Sotti Picasso 没有磁盘缓存。在这里查看 jake 的答案stackoverflow.com/questions/23280242/…
  • @billgates:嗯,我不知道自从 2 年前那个威胁之后发生了什么。最近的是这个 (goo.gl/1V4Vps) 或 Picasso 网页 (square.github.io/picasso),他们说 Picasso 提供“自动内存和磁盘缓存”。我并不是说不涉及 Http 客户端,但无论使用什么客户端(OkHttp、HttpUrlConnection ...),看起来磁盘都以某种方式涉及,并且 Picasso 正在通过其 Network.Policy 属性使用它。在这一点上对我来说并不完全清楚。
  • @Sotti:您提供的第一个链接(Github 问题)实际上证实了毕加索仍然依赖 OkHttp 来进行任何磁盘缓存。正如 Jake 所确认的,增加磁盘缓存大小的正确/唯一方法是增加 OkHttpDowloader 的缓存大小,这反过来又设置 Picasso 的 OkHttpClient 的缓存大小。
【解决方案3】:

更新:顺便说一句,链接是旧的,这是最新版本的更改:

https://github.com/square/picasso/blob/master/CHANGELOG.md

正如@Sotti 所说,PicassoAutomatic memory and disk caching,他们在介绍部分提到了这一点:(最后一部分)**

http://square.github.io/picasso/#introduction


在这个查询中,我们将得到 Glid 的解决方案,但不是 Picasso.how 我怎样才能重用图像无需重新下载不同的 尺寸ImageView

其实Picasso只有一个内存缓存,但是你可能想用OkHttp来做。

查看此链接:https://stackoverflow.com/a/18552559/4409113 其中说:

如果您指的是磁盘缓存,那么没有毕加索没有 目前支持。这是设计使然,因为磁盘层 缓存由HTTP layer 完成,没有区别。

也请查看:https://corner.squareup.com/2013/05/picasso-one-dot-oh.html

毕加索自动利用内存和磁盘缓存HTTP client) 来加速位图加载。对于开发,您可以 启用指示图像的彩色标记的显示 来源。

另外,检查这个问题:How to implement my own disk cache with picasso library - Android?

使用OkHttp将文件保存在自定义缓存目录中:

OkHttpClient okHttpClient = new OkHttpClient();
File customCacheDirectory = new File(Environment.getExternalStorageDirectory().getAbsoluteFile() + "/MyCache");
okHttpClient.setCache(new Cache(customCacheDirectory, Integer.MAX_VALUE));
OkHttpDownloader okHttpDownloader = new OkHttpDownloader(okHttpClient);
Picasso picasso = new Picasso.Builder(mainActivity).downloader(okHttpDownloader).build();
picasso.load(imageURL).into(viewHolder.image);

发件人:https://stackoverflow.com/a/33276054/4409113

如您所见,使用setCache


【讨论】:

  • 我认为值得指出的是,OkHttp 仍然只会缓存图像如果 HTTP 标头允许缓存 - 我曾经有一个客户抱怨图像没有重新加载每天然后图像文件有一个像Expires: Sun, 01 Jan 2017 00:00:00 GMT这样的标题。
  • @david.mihola - 嗯,谢谢分享经验。
  • 您的 Square 博客链接已有 3 年历史,版本为 1.0。今天 2.5.2 版本已经发布了一段时间,而 2.6 版本即将到来。你可以在他们的网页上看到毕加索有“自动内存和磁盘缓存”。 (goo.gl/tpTc1)
【解决方案4】:

默认情况下,毕加索不会调整图像大小。如果你像下一个一样打一个简单的电话......

Picasso.with(context).load("https://goo.gl/v9EkbF").into(imageView);

...毕加索正在缓存全尺寸图像。从那一刻起,每次调用同一个 URL 时,Picasso 都会重用该全尺寸图像,并让 GPU 调整视图的大小。

使用 resize() 方法你只是缓存调整大小的图像,如果你使用不同的大小,毕加索将需要重新下载图像。

不要使用 resize() 选项,你会得到更好的带宽使用,但要小心内存使用。

毕加索的默认设置

毕加索确实有自动内存和磁盘缓存。最近请求的任何图像都将在内存缓存中。如果它不存在,毕加索将检查磁盘缓存。如果它在磁盘上不可用,那么只有 Picasso 会启动网络请求。

所有请求的图像都存储在两个缓存中,直到必须删除它们以释放空间。

2.5.2 中的默认值是:

  • 15% 的可用应用程序 RAM 的 LRU 内存缓存
  • 2% 存储空间的磁盘缓存,最大 50MB 但不小于 5MB。
  • 如果 OkHttp 作为 Gradle 依赖项包含,Picasso 将使用 OkHttp 作为 Http 客户端。否则 Picasso 将回退到 HttpUrlConnection。

您可以像这样增加磁盘缓存(例如 100MB):

    Picasso picasso =  new Picasso
        .Builder(this)
        .downloader(new OkHttpDownloader(getCacheDir(), 100000000))
        .build();

    Picasso.setSingletonInstance(picasso);

更改磁盘缓存大小不会更改缓存策略。

内存策略

  • MemoryPolicy.NO_CACHE:不会从内存中提供图像。这不会避免从磁盘提供图像。为了避免磁盘看不起网络策略
  • MemoryPolicy.NO_STORE:图像不会存储在内存中。将此用于仅加载一次的图像。

例子

Picasso
        .with(context)
        .load(https://goo.gl/v9EkbF)
        .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
        .into(imageView);

网络政策

  • NetworkPolicy.NO_CACHE:不会从磁盘缓存中提供图像。
  • NetworkPolicy.OFFLINE:图像将(如果可能)仅从缓存(内存或磁盘)提供,但从不从网络提供。

例子:

Picasso
        .with(context)
        .load(https://goo.gl/v9EkbF)
        .networkPolicy(NetworkPolicy.NO_CACHE)
        .into(imageView);

内存和缓存注意事项

  • Glide 默认使用 RGB565 并将调整大小的图像缓存到 记忆。
  • 毕加索默认使用 RGB888 并将全尺寸图像缓存到 内存并让 GPU 在绘制时实时调整大小。

RGB565 是 RGB888 大小的一半。使用 RGB565 和更小图像的结果是 Picasso 的内存占用比 Glide 的更高(可能是 3x/4x)。

这些只是默认值。 Glide 可以配置为使用 RGB888,Picasso 可以配置为使用 RGB565。 Picasso 可以配置为仅将调整大小的图像(如 Glide)放入内存。

在相同的设置下,内存占用几乎相同。

带宽考虑

  • Glide 为每个大小缓存单独的文件。如果您加载另一个尺寸的 相同的图像,它会在之前再次下载,调整大小,然后 缓存。
  • Picasso 始终从缓存中获取全尺寸图像,然后让 GPU 将大小调整到视图中。

您可以要求 Glide 缓存所有内容,全尺寸图像和调整大小的图像,但默认情况下 Glide 的带宽消耗更高。

注意

Picasso 2.6 来了,我不知道有什么不同/新的。

来源

【讨论】:

  • 关于此的任何参考资料?:Picasso has "Automatic memory and disk caching 我在以下位置找不到:github.com/square/picasso/blob/master/CHANGELOG.md
  • 好点,它在所有项目下,我没看到:) +1,谢谢你提到它,我刚刚更新了答案。
  • 1) 毕加索没有磁盘缓存,它被委托给网络层 2) 即使调用 resize() 磁盘缓存(网络层)中的图像也不会调整大小。
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 2020-05-02
  • 1970-01-01
  • 2019-07-15
  • 2014-08-29
相关资源
最近更新 更多