【问题标题】:Two OkHttpClients with Two Caches - Odd Behavior两个带有两个缓存的 OkHttpClients - 奇怪的行为
【发布时间】:2016-07-13 17:37:31
【问题描述】:

我的应用目前有一个OkHttpClient (v3.2.0) 用于:

  1. 改造
  2. 毕加索
  3. 将图像/视频上传到云媒体服务
  4. HttpDataSource 用于视频使用 ExoPlayer (here's the implementation)

我想为改造和媒体用例使用单独的OkHttpClients,因为:

  1. 我想将它们的缓存分开
  2. 媒体OkHttpClient 将有一些特定的Interceptors 是改造者不应该有的

进行更改后,我为OkHttpClient 的每个实例提供了自己的Cache;两者都在应用程序的缓存目录中,一个使用目录http,一个使用media。两个实例的设置方式相同(在它们的Builders 中使用相同的CookieJarInterceptors;唯一的区别是传递给它们的Cache 实例不同)。缓存与 Picasso 完美配合,但与 OkHttpDataSource 一起使用时表现出奇怪的行为。

传递给 OkHttpDataSource 的 URL 是我的应用程序服务器上的一个端点,它重定向 (302) 到云媒体服务。这与我们用于图像/毕加索的过程相同,并且效果很好。

我对缓存的基本测试步骤是:

  1. 使用OkHttpDataSource 播放视频(我的应用服务器发回正确的缓存标头)
  2. FC 应用程序并重新打开它
  3. 将设备置于飞行模式
  4. 使用OkHttpDataSource 播放视频(即使没有互联网连接也应该播放)

当我使用OkHttpClient 时,一切正常。当我如上所述使用两个实例时,来自我的应用程序服务器的响应被缓存(302),但是当它尝试解析 Location 标头时,会抛出一个 IOException 说它无法解析地址。同样,当我只使用OkHttpClient 的一个实例时,这不会发生。此外,当我有 2 个实例时,如果我将 Retrofit 实例用于 OkHttpDataSource,则缓存工作正常。

我试图通过调试 DiskLruCache 来弄清楚发生了什么,但遇到了困难,因为附加调试器似乎有副作用。我能够观察到的是,在某些情况下,重定向 URL 的缓存条目被删除,因为它的 DiskLruCache.Entry.readable 始终设置为 false。据我所知,这是因为DiskLruCache.completeEditsuccess = false 调用,但我不确定为什么会这样。同样,仅使用 OkHttpClient 的一个实例,或使用 REST 实例而不是 OkHttpDataSource 的媒体实例时,这不是问题。

【问题讨论】:

    标签: android caching okhttp okhttp3


    【解决方案1】:

    OkHttp 的缓存只会存储完整的响应。第一次下载文件时,您是在读取整个响应正文,然后在该流上调用 close() 吗?

    【讨论】:

    • 我还没有明确验证整个文件是否已下载,但在我广泛的测试过程中,我播放了整个视频文件,这让我相信它下载了整个文件。另一点是,如果我恢复我的 2 个客户端代码,或者甚至使用其他客户端实例,它就可以工作。由于另一个客户端与 Retrofit 一起使用,Retrofit 是否有可能在其上调整一些参数来掩盖/修复问题?另外,我可以提供更多信息来帮助解决这个问题吗?
    • 只需重新阅读您的问题,虽然我没有明确调用ResponseBody.close(),但OkHttpDataSource.close() 确实从ExoPlayer 调用,并且调用ResponseBody.close()。我已经验证ResponseBody.close() 确实在使用一个OkHttpClient 实例(并且缓存有效)和使用两个(并且缓存不起作用)时被调用。在这两种情况下,我都会播放整个视频,所以我会假设整个视频都被阅读了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    相关资源
    最近更新 更多