I use Picasso to download images from the web, and display them in a RecyclerView.
private Picasso createPicasso(Context context){
OkHttpClient picassoClient = new OkHttpClient();
picassoClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
try {
Map authHeaders = BackendServiceClient.buildAuthHeaders();
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", (String) authHeaders.get("Authorization"))
.build();
return chain.proceed(newRequest);
} catch (CredentialNotStoredException e) {
e.printStackTrace();
}
return chain.proceed(chain.request().newBuilder().build());
}
});
return new Picasso.Builder(context)
.downloader(new OkHttpDownloader(picassoClient))
.build();
}
Usage:
ImageDownloader.getSharedInstance().getPicasso(context)
.load(url)
.placeholder(R.drawable.head_big) //
.error(R.drawable.head_big) //
.tag(context)
.into(holder.personPhoto);
Downloading and displaying the images works as expected, but if I scroll through the list, the images gets fetched from the web again and were not cached.
How is it possible to always cache them on the disk and memory.
Switched to Glide which improves memory footprint and caching works out of the box.
https://github.com/bumptech/glide
http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en
Related
I am developing an Android application which is displaying lots of images. I am using Picasso for loading the image and using its default caching strategy. Now what I want is to modify the caching and suppose if user has seen an image today it will be there in the cache for next seven days and each time user visit that particular page Picasso load the image from cache, after 7 days the image will be cleared from cache and do a fresh caching again. Someone, please help me I am lost.
private void PicassoConfig() {
Picasso.Builder builder = new Picasso.Builder(this);
builder.downloader(new OkHttp3Downloader (this, Constants.MAX_DISK_CACHE_SIZE));
Picasso built = builder.build();
Picasso.setSingletonInstance(built);
}
then
Picasso.get().load(cardList.get(i).
getImage()).noFade().priority(Picasso.Priority.HIGH).
placeholder(R.drawable.placehoder_image).
transform(new com.squareup.picasso.Transformation()
I want the image to be in the cache for a week.
Create a custom OkHttp interceptor and add to Picasso.
public Interceptor provideCacheInterceptor(final int maxDays) {
return new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(maxDays, TimeUnit.DAYS)
.build();
return response.newBuilder()
.header(Constants.CACHE_CONTROL, cacheControl.toString())
.build();
}
};
}
Now, Add this to Gradle
compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2'
Now attach Custom OkHttpClient to Picasso. More info here
okhttp3.OkHttpClient okHttp3Client = new okhttp3.OkHttpClient();
int MaxCacheDays = 7;
okHttp3Client.addNetworkInterceptor(provideCacheInterceptor(MaxCacheDays));
OkHttp3Downloader okHttp3Downloader = new OkHttp3Downloader(okHttp3Client);
Picasso picasso = new Picasso.Builder(context)
.downloader(new CustomOkHttp3Downloader(client))
.build();
I need to pass a header when I try to show a image using Picasso.
Can any one suggest how to add header to picasso while viewing the image.
You can use downloader for that:
https://github.com/JakeWharton/picasso2-okhttp3-downloader
Example:
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("custom-header", "custom-header-value")
.build();
return chain.proceed(newRequest);
}
})
.build();
Picasso picasso = new Picasso.Builder(context)
.downloader(new OkHttp3Downloader(client))
.build();
Keep in mind that if you are using OkHttpClient already, you should use that instance or create new one using client.newBuilder(). This way, both instances will be using the same request queue.
I am using Picasso to download images and show them from the server. I need to set basic Aucathention to my requests. And because of that i used this:
'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
and my code is:
String url = "images/download/" + images.getiId();
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("user_auth", user_auth)
.addHeader("user_password", user_pass)
.build();
return chain.proceed(newRequest);
}
})
.build();
Picasso picasso = new Picasso.Builder(context)
.downloader(new OkHttp3Downloader(client))
.build();
picasso.load(url)
.error(R.drawable.error_icon_128)
.into(view);
}
but every time it can't download images And I can't see response code from the server. How can I see response code?
Thank you.
I am trying to load an image from url, but adding authorization token. Picasso does not want at all to load it if i add networkPolicy(NetworkPolicy.OFFLINE) is there any problem with it ?
my code :
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + userPrefs.accessToken().get())
.build();
return chain.proceed(newRequest);
}
})
.build();
Picasso picasso = new Picasso.Builder(getActivity())
.downloader(new OkHttp3Downloader(client))
.build();
picasso
.load(URL)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(ivUserImage, new Callback() {
#Override
public void onSuccess() {
Toast.makeText(getActivity(), "+", Toast.LENGTH_SHORT).show();
}
#Override
public void onError() {
Toast.makeText(getActivity(), "-", Toast.LENGTH_SHORT).show();
}
});
Yes, it is
We have three enums to pass to networkPolicy
NO_CACHE
Skips checking the disk cache and forces loading through the network.
NO_STORE
Skips storing the result into the disk cache.
OFFLINE
Forces the request through the disk cache only, skipping network.
So if we use OFFLINE, It will skip the Network.
Also please read this API for Picasso
The easy way to use the offline policy
Picasso.with( getApplicationContext() ).load( link ).networkPolicy( NetworkPolicy.OFFLINE ).placeholder( R.drawable.notification ).into( imageView, new Callback() {
#Override
public void onSuccess()
{
}
#Override
public void onError() {
Picasso.with( getApplicationContext() ).load( link ).placeholder( R.drawable.notification ).into( imageView );
}
} );
In my application I'm using custom downloader to download images because server requires additional authorisation in request header. I'm trying to load downloaded images in offline mode, but when I'm using this custom downloader Picasso isn't loading images. Anyone could help?
OkHttpClient picassoClient = new OkHttpClient();
picassoClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader(RestUtils.HEADER, hash)
.build();
return chain.proceed(newRequest);
}
}
);
Picasso picasso = new Picasso.Builder(mContext)
.downloader(new OkHttpDownloader(picassoClient)).build();
picasso.setIndicatorsEnabled(true);
picasso.invalidate(RestUtils.getUrl(url));
if (DeviceUtility.isOnline(mContext)) {
picasso.load(RestUtils.getUrl(url))
.networkPolicy(
DeviceUtility.isOnline(mContext) ?
NetworkPolicy.NO_CACHE : NetworkPolicy.OFFLINE)
.resize(200, 200)
.centerCrop()
.into(viewHolder.mImgvPicture);
} else {
picasso.load(RestUtils.getUrl(url))
.networkPolicy(
DeviceUtility.isOnline(mContext) ?
NetworkPolicy.NO_CACHE : NetworkPolicy.OFFLINE)
.resize(200, 200)
.centerCrop()
.into(viewHolder.mImgvPicture);
}
You invalidate the URL right before getting it from cache:
picasso.invalidate(RestUtils.getUrl(url));
Try to invalidate only if the device is connected.