I am using picasso to fetch images from server.
This is what i am using.
Picasso.with(getApplicationContext()).load(imageURL)
.placeholder(R.drawable.card_loading)
.fit().centerCrop()
.into(imageView);
The above code should cache the images, but when i update the same image on server, without changing its URL, it starts displaying the new image on app, whereas it should display the cached old image on the app.
In some devices it was displaying the older images, i closed and restart the app multiple times, then it started displaying the new images on those devices as well.
My Question is that how long picasso keep an image in cache, and how can i increase this from server or client
I'm not sure how long cache file valid. But you can change cache file validity with incoming http response header. Basically you can create interceptor and add new header with "Cache-Control" name.
OkHttpClient httpClient = new OkHttpClient();
httpClient.networkInterceptors().add(new Interceptor(){
#Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder().header("Cache-Control", "max-age=" + (60 * 60 * 24 * 365)).build();
}
});
After that you can pass it to picasso as a http client
Related
I am using Picasso for image loading. Picasso doesn't have a disk cache. OkHttp maintains an HTTP cache that is controlled by HTTP cache headers. I want to set an expiry for disk cached images so added cache-control headers in HTTP response cache-control: public, max-age=7200 but it is not respecting cache headers. The current behavior is the default HTTPResponseCache which honors RFC 7234.
Is there anything we are missing?
You can rewrite cache headers in the response with a network interceptor. Here's an example from the OkHttp interceptors doc to get you started:
/** Dangerous interceptor that rewrites the server's cache-control header. */
private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
#Override public Response intercept(Interceptor.Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.header("Cache-Control", "max-age=60")
.build();
}
};
Note that you might need to remove headers from the server's response to get your desired caching behavior.
Note also that it's strictly better to fix the server to do what you want; that way it'll work correctly on iOS and on the web.
I have a set url (ex: http://mywebsite.com/cawn28xd/user_avatar) I call for imageloading that redirects to another link that may or may not be different.
I want to be able to either intercept the 302 redirect and grab the url so the imageloader will not cache that specific url (This brings up the issue the 302 redirect url will be cached, but should be handled on the setShouldCache(false) call for the request)
OR
I want to be able to invalidate or remove caching from the specified URL using Google Volley and it's imageloader.
I am using the singleton class provided from the android developers guide including the default image loading request:
RequestEntity.getInstance(mContext).getImageLoader().get(mImageURL,
ImageLoader.getImageListener(mImageView,
R.drawable.default_avatar, R.drawable.default_avatar));
The imageloader provided from android volley uses a cachekey in order to cache requests, but during its process it makes a simple image request.
So just use a request:
Request<Bitmap> imageRequest = new ImageRequest(requestUrl, listener,
maxWidth, maxHeight, scaleType, Bitmap.Config.RGB_565, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
imageView.setImageResource(R.drawable.default_avatar);
}
});
imageRequest.setShouldCache(false);
RequestEntity.getInstance(this).getRequestQueue().add(req);
I'm building an Android application which uses Volley to load images from the web.
I'm using an LruCache with Volley to cache bitmaps in memory, and this is fine. In addition, I'd like Volley to leverage the built in support for http disk based caching using HttpResponseCache.
I implemented the example in the given link, but I noticed that nothing is being cached in the HttpResponseCache (I checked by sampling the HitCount field in the cache object).
After sniffing around in the Volley source code, I found that Volley manually removes the caching flag when opening a URLConnection:
private URLConnection openConnection(URL url, Request<?> request) throws IOException {
URLConnection connection = createConnection(url);
int timeoutMs = request.getTimeoutMs();
connection.setConnectTimeout(timeoutMs);
connection.setReadTimeout(timeoutMs);
connection.setUseCaches(false); // <-- Disables the caching
connection.setDoInput(true);
// use caller-provided custom SslSocketFactory, if any, for HTTPS
if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) {
((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
}
return connection;
}
You can see this code for yourself here: Volley - HurlStack (line 167)
The moment I comment out this line, the HttpResponseCahce works as expected.
My question is: Why does Volley disable the UseCaches flag in all URLConnections, and what is the risk / side-effects of removing this?
This may be a bug in Picasso, but I wanted to post to StackOverflow first.
I am getting the error "Received response with 0 content-length" when the responses are being read from the cache from disk. I can reproduce this error every time by
1) Run my app without OKHttp in classpath. Let pictures load
2) Add OkHttp into classpath, I get that error.
I added Picasso source to my project to investigate further. I found out that
1) Turning off caching connection.setUseCaches(false); will bypass the error (since it ignores the cache)
2) I found the switch in the Picasso source where it checks if OkHttp was available
try {
Class.forName("com.squareup.okhttp.OkHttpClient");
okHttpClient = true;
} catch (ClassNotFoundException ignored) {}
and was able to reproduce the bug by hardcoding true, then false between runs.
I want to solve this problem so I can use OKHttp (and provide a viable upgrade for my current users) and all the benefits that come with it. I also have seen this "reading response with no content-length from cache" problem in other cases in my live environment. Once I get into the state with a bad response in cache, the pictures will never show up.
OkHttpClient okHttpClient = new OkHttpClient();
RestAdapter restAdapter = new RestAdapter.Builder().setClient(new OkClient(okHttpClient)).build();
OkHttpDownloader downloader = new OkHttpDownloader(okHttpClient);
Picasso picasso = new Picasso.Builder(this).downloader(downloader).build();
Source: https://stackoverflow.com/a/23832172/2158970
I want to load a picture with Picasso from internet, and without connectivity, from disk cache. The cache is writing fine (the picture is in the cache dir). But when reading I get this log:
Sending progress READING_FROM_CACHE
Cache content not available or expired or disabled
I have retrofit and okhttp in my project for requests. And this picture is loaded with this CODE:
// Obtain the cache directory
File cacheDir = getActivity().getCacheDir();
// Create a response cache using the cache directory and size restriction
HttpResponseCache responseCache = null;
try {
responseCache = new HttpResponseCache(
cacheDir,
10 * 1024 * 1024);
} catch (IOException e) {
e.printStackTrace();
}
// Prepare OkHttp
OkHttpClient httpClient = new OkHttpClient();
httpClient.setResponseCache(responseCache);
// Build Picasso with this custom Downloader
Picasso picasso = new Picasso.Builder(getActivity())
.downloader(new OkHttpDownloader(httpClient))
.build();
picasso.setDebugging(true);
picasso.with(getActivity())
.load(profilePicUrl) // url picture
.resize(180, 180)
.centerCrop()
.placeholder(R.drawable.ic_int_profile_no_photo)
.into(mProfilePic); //ImageView
The result is that without connectivity, the picture don't load, but the picture is in the cache dir of picasso (and the log shows that message).
Ideas
I think that if I use a custom Download for Picasso I don't must to modify my retrofit requests headers (RequestInterceptor -> intercept). I have many POST and GET request and I'd like leave them as are.
Some links that I have checked
How to implement my own disk cache with picasso library - Android?
https://github.com/square/picasso/issues/237
How to retrieve images from cache memory in picasso?
Thanks in advance.