Picasso: Loading cached image from disk too much slow - android

So, I was starting my project and wants to use Picasso in my project because its popular and used by many projects out there.
I included picasso using gradle and tried loading facebook profile url with this. http://graph.facebook.com/rohitiskul/picture.
It worked very well. It loaded image from network without any issues. I restarted the app.(Without actually killing the process). It showed me the same image instantly cached in Memory.
But then, I killed the app (force stop) and restarted. It took almost 10+ seconds to load the image. And that image was loading from the disk when I checked in the debug logs.
My code looks like this -
In MainActivity-
Picasso.with(context)
.load("http://graph.facebook.com/rohitiskul/picture")
.into(imageView);
In application class-
Picasso picasso = new Picasso.Builder(this)
.indicatorsEnabled(true).loggingEnabled(true).build()
Picasso.setSingletonInstance(picasso);
Anyone with the similar problem? Any solution would be helpful.
I tried loading same Url with UniversalImageLoader and it was fast when fetching cached image from disk.
Edit
Earlier while playing with my app, I found out that Picasso wasn't loading the disk cached image when device was offline.

I encounter the same problem,
but find only slow for the first image, later images will be fast.
Probably it needs a warm-up (loading index cache) ?

Okay i got your problem. I have fixed it by doing this
Picasso.with(context)
.load("http://graph.facebook.com/rohitiskul/picture")
.networkPolicy(NetworkPolicy.OFFLINE)
.into(imageView, new Callback() {
#Override
public void onSuccess() { }
#Override
public void onError() {
// Try again online if cache failed
Picasso.with(context)
.load("http://graph.facebook.com/rohitiskul/picture")
.into(imageView);
}
});
Explanation:
Picasso will look for images in cache.
If it failed only then image will be downloaded over network. In your case from facebook.

This issue I had also faced earlier, with this what I understood that Picasso refer the cached image based on image name mentioned in the URL.
In your case you don't have image name in URL like 'image1.jpg'. Due to which Picasso is finding it difficult to read from cache and it downloads the image everytime
You can give a try to image containing the image name in URL and that will work

Picasso doesn't offer disk cache out of the box. Instead, it relies on an Http Cache.
Make sure you add OkHttp to your dependency list.

Add a string identifier with the stableKey method when making the request so Picasso can identify your requests and quickly load it from the cache.
Example:
Picasso.Builder(context).loggingEnabled(true).build()
.load(imageUrl)
.stableKey("myImage")
.into(imageView)

Related

Glide Does not use Cached Image

Hi I am using Glide to load image and after following many posts I tried to implement Glide caching using
RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL).centerCrop()
Glide.with(mContext)
.load(imageUrl)
.transition(ImageUtil.crossFadeTransition())
.apply(ImageUtil.requestOptionsForSlider())
.listener(glideRequestListner)
.into(imageView)
My knowledge is that if I use diskCacheStrategy(DiskCacheStrategy.ALL) then the above Glide image loading code will automatically use cache if available, or download if not, right?
But I see everytime the code is called, (checking my internet speed meter) that it is always fetching/downloading from the given url (even though I can see the app memory size is increasing).
I even tried this code also-
val future: FutureTarget<File> = Glide.with(mContext)
.load(imageUrl)
.downloadOnly(500, 500)
Nothing seems to work
What should I do so that Glide uses cache if available?What is wrong with my conception about the caching implementation? Any help is very much appreciated!
Are you sure it is downloading again ? did you try disabling internet just before loading the images ?
Otherwise, is your image URL always the same for the same image ? (as Glide uses it as a cache key).
You can use this in the following calls to check if images are in cache:
Glide.with(fragment)
.load(url)
.onlyRetrieveFromCache(true)
.into(imageView);

glide take time to load image even if image load from cache?

I have RecyclerView where image load from server URL. so I use Glide library to load an image, glide store image into cache to reload as fast as possible.
I use a placeholder() as a loader for loading image first time, but if I off the internet and start app its still load placeholder first and then load an image into ImageView.
So, my question is, is there any way to load an image into ImageView so user experience like smoothness (offline) app while loading images
Glide.with(context)
.load(www.abc.com/abcd.jpg)
.placeholder(R.drawable.placeholder)
.into(viewHolder.ivSleepImage)
you can check this app Walking UP it loads image first time than there is no loader, and next time when image load means when you open app image already loaded in list.
Please somebody help me to achieve this task
There are 2 ways you can do that task but it can be very lengthy because storing and loading is not the way to approach in the android development
1.Store the data in the cache
2.store data in the database
the cache strategy is relatively easy. as you are requesting the data from the server if the connection is not available then you have to load data from the cache. Same can be said from the database but it is very lengthy and can be very slow.
A quick solution to your problem would be to add diskCacheStrategy to your Glide call. This would help you cache ALL versions of your image and thus reduce load-time. Here's an implementation:
Glide.with(context)
.load(www.abc.com/abcd.jpg)
.placeholder(R.drawable.placeholder)
.into(viewHolder.ivSleepImage)
.diskCacheStrategy(DiskCacheStrategy.ALL)
I hope this helps. Merry coding!

Picasso Caching Doesn't Appear to be working

I am using Picasso to handle image loading and caching in my Android Udacity project and I am noticing the caching is not working as I'd expect:
As you can see on the left fragment, the image has already loaded in an earlier thread. Now, with the same URL link, I am asking Picasso to place that image in the fragment on the right.
Here is the code which generates the grid view on the left fragment (and occurs first):
https://github.com/esend7881/udacity-android-popmovie/blob/a9a1b9a19a37594bb5edd736b7ec59229fb5905a/app/src/main/java/com/ericsender/android_nanodegree/popmovie/adapters/GridViewAdapter.java#L71
String load = String.format(sImgUrl, sImgSize, movie.poster_path);
Picasso.with(mContext.getApplicationContext())
.load(load)
.placeholder(R.drawable.abc_btn_rating_star_on_mtrl_alpha)
.error(R.drawable.abc_btn_rating_star_off_mtrl_alpha)
.resize(550, 775)
.into(viewHolder.imageView);
And then here is the code which runs in the right fragment:
https://github.com/esend7881/udacity-android-popmovie/blob/a9a1b9a19a37594bb5edd736b7ec59229fb5905a/app/src/main/java/com/ericsender/android_nanodegree/popmovie/fragments/MovieDetailsFragment.java#L308
Picasso.with(getActivity().getApplicationContext())
.load(String.format(sImgUrl, sImgSize, mMovieObj.poster_path))
.error(R.drawable.blank)
.fit()// .resize(366, 516)
.into(mMovieThumb, new com.squareup.picasso.Callback() {
#Override
public void onSuccess() {
Utils.log(sw.toString());
Utils.hideViewSafe(mMovieThumbProgress);
}
#Override
public void onError() {
Utils.log(sw.toString());
Utils.hideViewSafe(mMovieThumbProgress);
}
});
I am using the same application context in each as well as the load text:
String.format(sImgUrl, sImgSize, mMovieObj.poster_path))
and
getActivity().getApplicationContext()
So, I would think Picasso ought to detect when the exact same URL load link appears in the same context within a short period of time from each other and Picasso would then load the exact same image back into the app.
If this is not how Picasso caching works, then how does it?
As a comment mentioned, I'd guess this is affected by the size of the image being different in both fragments.
I'd recommend using https://github.com/facebook/fresco instead of picasso. It's more efficient, especially with different sizes. You can also directly access cached files if required https://github.com/facebook/fresco/issues/80
It's probably related to the HTTP headers received when getting the image that do not allow caching, as Picasso relies on an HTTP component to do the caching.
Try uploading your image on imgur, try hardcoding that path and see if it works. If that's the case, you'll have to find a workaround on how to get the image from the movie database.

Glide : How to find if the image is already cached and use the cached version?

Scenario:
I have a large GIF image which I want to cache the first time user opens the app using Glide - Image Loading and Caching library. After that whenever user opens the app, I want to show the cached version if present. This GIF URL will expire after a given interval. When it expires, I fetch the new GIF URL and display/cache that for future use.
What I tried:
I went through Caching and Cache Invalidation on Glide's github page. I also went though the Google Group thread Ensuring That Images Loaded Only Come From Disk Cache, which shows how to get the image form cache. I also went through How to invalidate Glide cache for some specific images question.
From the links above I see the following code sniplet which shows how to load the image from cache. However this only tries to get the image from cache. If its not present in cache, it doesn't try to get from the network and fails:
Glide.with(TheActivity.this)
.using(new StreamModelLoader<String>() {
#Override
public DataFetcher<InputStream> getResourceFetcher(final String model, int i, int i1) {
return new DataFetcher<InputStream>() {
#Override
public InputStream loadData(Priority priority) throws Exception {
throw new IOException();
}
#Override
public void cleanup() {
}
#Override
public String getId() {
return model;
}
#Override
public void cancel() {
}
};
}
})
.load("http://sampleurl.com/sample.gif")
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(theImageView);
Questions:
Is there a cleaner way to achieve the following: Show the GIF image from the cache if present else download the GIF, cache it for later use and show it in the ImageView.
The caching article above mentions the following:
In practice, the best way to invalidate a cache file is to change
your identifier when the content changes (url, uri, file path etc)
The server sends a different URL to the app when the previous one expires. In this case, I believe the old image will eventually be Garbage Collected? Is there a way to force remove the image from the cache?
On a similar note, is there a way to prevent the Garbage Collection of an image with specific key (to prevent downloading the large file again) and then later instruct to delete the old image from cache when the URL changes?
You don't need a custom ModelLoader to show the GIF from cache if present and fetch it otherwise, that's actually Glide's default behavior. Just using a standard load line should work fine:
Glide.with(TheActivity.this)
.load("http://sampleurl.com/sample.gif")
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(theImageView);
Your code will prevent Glide from downloading the GIF and will only show the GIF if it is already cached, which it sounds like you don't want.
Yes, the old image will eventually be removed. By default Glide uses an LRU cache, so when the cache is full, the least recently used image will be removed. You can easily customize the size of the cache to help this along if you want. See the Configuration wiki page for how to change the cache size.
Unfortunately there isn't any way to influence the contents of the cache directly. You cannot either remove an item explicitly, or force one to be kept. In practice with an appropriate disk cache size you usually don't need to worry about doing either. If you display your image often enough, it won't be evicted. If you try to cache additional items and run out of space in the cache, older items will be evicted automatically to make space.
Glide.with(context)
.load("http://sampleurl.com/sample.gif")
.skipMemoryCache(true)
.into(imageView);
You already noticed that we called .skipMemoryCache(true) to specifically tell Glide to skip the memory cache. This means that Glide will not put the image in the memory cache. It's important to understand, that this only affects the memory cache! Glide will still utilize the disk cache to avoid another network request for the next request to the same image URL.for more read this
Glide Cache & request optimization.
Happy coding!!

How to invalidate Glide cache for some specific images

I'm writing an app which needs to load a lot of images from the internet (a manga reader). I need to cache some thumbnail images for offline use, any others should be cleared when app closed.
I read some about cache invalidation on Glide page, they said the best way is to change the content url, but how Glide know if it is a modified url of old content or a new one? I'm new to Glide here.
https://github.com/bumptech/glide/wiki/Caching-and-Cache-Invalidation
Thank in advance :)
You can use following to load image:
Glide.with(context)
.signature(new StringSignature(yourVersionMetadata))
.into(imageView)
Just change yourVersionMetadata when you load image and it will not load from cache if yourVersionMetadata is different.

Categories

Resources