如何实际上进行图像缓存:毕加索的做法

9
我想知道 Picasso 库在应用程序中如何缓存图像。我知道它使用 HttpHeaders 来检查是否从网络获取图像。
但是,它是否有任何时间框架来缓存图像?比如说一天后失效之类的?
问题是我的项目从网络加载大量的小图片。有时候,新的图片会在下次启动时反映出来。但是有时候就不会。
最糟糕的是,一些图片虽然在同一时间进行了更改,但有些图片却没有反映出来。但是,当我卸载应用程序时,所有的图片都反映出了更改(当然)。
Picasso 应该有关于缓存的内容。
请不要告诉我使用 OkHttp 来控制 Picasso 中的缓存。
我的项目正在使用 Apache 的 AsyncHttpClient,而且太过臃肿,无法更新。(当然不是我,我只会使用 UrlConnection 创建一个小型的网络助手,而不是实现整个 AsyncHttpClient。)
总之,任何想法或指针都将不胜感激。
底线:不使用 OkHttp。只想了解 Picasso 中的缓存控制机制。
谢谢!
2个回答

15

Picasso 只有一个内存缓存。

如果图片在内存缓存中,它会使用该缓存。否则,当图片从其远程来源(网络、内容提供商、文件系统等)加载时,它将被放置在内存缓存中以便于未来查找。

内存缓存是一个LRU(最近最少使用)算法,因此使用频率越高的图像,就越有可能保留在缓存中。不经常请求的图像会随着时间的推移而被清除出缓存。没有时间方面的驱逐策略,内存缓存也不尊重任何HTTP头部(如果图像来自网络)的缓存语义。

Picasso 没有磁盘缓存。它完全依赖于正在使用的 HTTP 客户端 (OkHttp 或 HttpUrlConnection) 提供此功能。自动安装缓存对于OkHttp或HttpUrlConnection中的任何一个都将被使用。如果您使用自定义的HTTP客户端,则启用缓存的责任在调用方身上。


谢谢Jake。它本身已经相当详细了。但是,你能否更详细地解释一下“内存缓存不遵守任何HTTP头的缓存语义”?还有关于“OkHttp和HttpUrlConneciton都将安装缓存”的问题?坦白地说,我根本不想碰那个AsyncHttpClient机制。我看到Picasso Source中有“Cache”接口,而LruCache正在实现它。通过分叉Picasso来实现自己的缓存机制是否明智?如果我实现自己的缓存,我可以像Ciprian在下面提到的那样设置按时间框架清除它的触发器吗? - Aung Pyae
@JakeWharton,你太棒了!你可能会对我在括号中提出的“额外”问题感兴趣。这个问题让我很困惑。感谢你一直以来的支持,我们都是你的狂热粉丝! - Fattie

4
据我所知,Picasso本身不会清除缓存,因此在我们的应用程序中我们需要手动触发这个过程。要执行此操作的代码如下:
private static final String PICASSO_CACHE = "picasso-cache";

public static void clearCache(Context context) {
    final File cache = new File(
            context.getApplicationContext().getCacheDir(),
            PICASSO_CACHE);
    if (cache.exists()) {
        deleteFolder(cache);
    }
}

private static void deleteFolder(File fileOrDirectory) {
    if (fileOrDirectory.isDirectory()) {
        for (File child : fileOrDirectory.listFiles())
            deleteFolder(child);
    }
    fileOrDirectory.delete();
}

您可以根据您的应用程序需要,每天/每周触发此清理工作程序。

3
只有在使用OkHttp或HttpUrlConnection时才有效,而文章明确指出他没有使用这两种方法。 - Jake Wharton
好的,我们正在使用OkHttp。 - Ciprian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接