使用Picasso和自定义磁盘缓存

时间:2014-04-24 21:29:48

标签: android caching picasso

Volley库中,NetworkImageView类需要ImageLoader来处理所有图像请求,方法是在ImageCache实现中搜索它们,用户可以自由选择缓存应该如何工作,图像的位置和名称。

我正在从Volley切换到Retrofit,对于我决定尝试Picasso的图片。

使用前一个库,我在每个包含图像URL的项目中都有一个String参数,然后我使用了myNetworkImageView.setImageUrl(item.getURL()),它能够确定图像是否缓存在磁盘上。如果图像存在于缓存文件夹中,则加载图像,否则将其下载并加载。

我希望能够对Picasso做同样的事情,是否可以使用Picasso API或我应该自己编写此类功能?

我正在考虑将图像下载到文件夹(缓存文件夹),并在完成时使用Picasso.with(mContext).load(File downloadedimage)。这是正确的方法还是有任何最佳做法?

4 个答案:

答案 0 :(得分:48)

Picasso没有磁盘缓存。它委托您用于该功能的任何HTTP客户端(依赖于缓存控制的HTTP缓存语义)。因此,您寻求的行为是免费的。

如果本地缓存中不存在图像(并且该图像未过期),则基础HTTP客户端将仅通过网络下载图像。

也就是说,您可以java.net.HttpUrlConnection(通过ResponseCache或OkHttp(通过ResponseCacheOkResponseCache)创建自定义缓存实施你想要的格式的文件。我强烈建议不要这样做。

让Picasso和HTTP客户端为您完成工作!

您可以在setIndicatorsEnabled(true)实例上调用Picasso以查看正在加载图像的指示符。它看起来像这样:

如果您从未看到蓝色指示符,则可能是您的远程图像未包含正确的缓存标头以启用缓存到磁盘。

答案 1 :(得分:12)

如果你的项目正在使用okhttp library,那么picasso会自动将其用作默认下载程序,并且磁盘caché将自动运行。

假设您使用的是Android Studio,只需在dependencies文件的build.gradle下添加这两行,即可进行设置。 (没有需要毕加索的额外配置)

dependencies {
    [...]
    compile 'com.squareup.okhttp:okhttp:2.+'
    compile 'com.squareup.okhttp:okhttp-urlconnection:2.+'
}

答案 2 :(得分:2)

正如许多人在这里正确指出的那样,OkHttpClient是进行缓存的方法。

使用OkHttp进行缓存时,您可能还希望使用OkHttp 拦截器在HTTP响应中获得对Cache-Control标头的更多控制,请参阅我的回复here

答案 3 :(得分:1)

以前编写的是,Picasso使用底层Http客户端的缓存。

HttpUrlConnection的内置缓存无法在真正的离线模式下工作,如果由于某些原因使用OkHttpClient ,则可以使用自己的磁盘缓存实现(当然基于在 var queryString = 'select Tweet.Label, Tweet.TDate, Tweet.TLink, Author.Lable, Author.ALink from Tweet, Author where Tweet.AuthorID IN (select ID from Author where Lable = ?) AND Author.ID IN (select ID from Author where Lable = ?)'; var query = connection.query(queryString, [term,term], function(err, rows) { console.log(rows); //res.write(JSON.stringify(rows)); var tweets = JSON.parse(JSON.stringify(rows)); var queries_made = 0; var queries_success = 0; tweets.forEach(function(tweet){ connection.query('select Label from Hashtag where ID IN (select HashID from tweethashs where TweetID IN (select ID from Tweet where Label = ?))', [tweet.Label], function(err, rows1) { res.write("Author: "); res.write("<a href='" + tweet.ALink + "' target='_blank'>" + tweet.Lable + "</a> <br/>"); res.write("Date: " + tweet.TDate + "<br/>"); res.write("Tweet: " + "<a href='" + tweet.TLink + "' target='_blank'>" + tweet.Label + "</a> <br/>"); var tweet1 = JSON.parse(JSON.stringify(rows1)); for(var j in tweet1){ res.write("Hashtag: "); res.write(tweet1[j].Label); } res.write("<br/><br/>"); queries_success++; if(queries_made==queries_success) res.end(); } ); queries_made++; }) }); )。

其中一种方法是将DiskLruCache和程序整个逻辑子类化为:

com.squareup.picasso.UrlConnectionDownloader

然后使用您的实现:

@Override
public Response load(final Uri uri, int networkPolicy) throws IOException {
...
}

这是new Picasso.Builder(context).downloader(<your_downloader>).build(); 的实现,它与磁盘缓存一起使用,即使在完全脱机模式下也可以发送到Picasso位图:

UrlConnectionDownloader