I want to prefetch images using Picasso and save them all to disk upon opening the app (no lazy loading on the fly). To make sure the cache is big enough I am using the following code in my Application onCreate
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
OkHttpClient client = new OkHttpClient.Builder()
.cache(new Cache(directory, Integer.MAX_VALUE))
.build();
OkHttp3Downloader okHttp3Downloader = new OkHttp3Downloader(client);
Picasso.Builder builder = new Picasso.Builder(this);
builder.downloader(okHttp3Downloader);
Picasso built = builder.build();
built.setIndicatorsEnabled(false);
built.setLoggingEnabled(false);
Picasso.setSingletonInstance(built);
So here I set my cache size to Integer.MAX_VALUE which should be big enough ;)
I use code similar to this line to prefetch the image: Picasso.with(context).load(url).fetch();.
Now when I kill my internet and mobile data, no images are loaded even though the my code is fetching items. Any ideas why?
Maybe the problem is loosing state. Did you try to extend Application class (like this) and keep Picasso instance here?
In similar situation when I needed to fetch lots of images, I save them to internal memory (not just in some cache) - to prevent from reloading, and save uri's to files into SQLite and then use Picasso to work with such URI's. (don't forget to check that user don't delete anything).
In the end I created my own image manager that downloads and store images (still using picasso to download them).
Here is my approach:
In Application's onCreate method do:
Picasso picasso = new Picasso.Builder(this)
.downloader(new OkHttp3Downloader(this,Integer.MAX_VALUE))
.build();
picasso.setIndicatorsEnabled(BuildConfig.DEBUG);
picasso.setLoggingEnabled(BuildConfig.DEBUG);
Picasso.setSingletonInstance(picasso);
And then wherever you want to load your images call this for each image's url:
Picasso.with(context).load(url).fetch();
From doc:
fetch()
Asynchronously fulfills the request without a ImageView or Target. This is useful when you want to warm up the cache with an image.
You can even pass in callback to check for possible errors
Related
How can I ommit disc caching in per request basis as in Glide with setDiscCacheStrategy (other than downloadimg the image normally and than evic it from disc cachd)
Assuming you use ImageRequestBuilder to build ImageRequest objects, you need to call disableDiskCache() on the builder.
For example:
ImageRequest request = ImageRequestBuilder
.newBuilderWithSource(uri)
.disableDiskCache()
.build();
if its just for debug builds you can do it another way. in my case i was not using imageRequestBuilder. so i just added a random number as a query param to the url fresco is loading. it will make fresco get a new image everytime almost. no cache.
I'm developing an Android application I have implemented a custom listview with a header (ImageView) and a content (different textview), all data the data are obtained from a json that contais all text and a link that directs to an image.
I have to implement a function that download images in a local folder and instead of downloading them from the internet to fetch from the local folder.
I have to problem :
1) I have to implement a function that download in local storage the images during the parsing of my JSON. If the parser found an image must be downlaoded.
2) After the parsing the downloaded images must be associated to the local images.
3) When i try to show all the data, the images must be showed from local.
(Actually I use volley to load images from internet)
How i can do this ? How i can maintain the link beetween images and data
[
{
"date":"MY DATE",
"desc":"My description",
"id":"1",
"img":"http:\/\/MYURL\/FOLDER\/homeone.jpg",
"text":" My text",
"title":"My title"
}
]
***** EDIT 1 *****
I have a problem with Picasso library, I don't understand how I can implement the cache. For example, after the parsing of my JSON I can get the url of my JSON item.
In this case http:\/\/MYURL\/FOLDER\/homeone.jpg now I have to save the image to he local storage.
Picasso.with(this)
.load(url)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(imageView);
This is the code that I have found in another question on StackOverflow, this could help me to create the cache ? If yes, how i can specify the cache folder ?
Is is possible only save the images on local storage ? This cache is "permanent" or all data will deleted when the application is re-started ?
What you are trying to achive is implemented in Picasso
Try to avoid wheel inventing :)
UPD:
Picasso cache images automatically and you don't need to care about this thing at all. However, you can try this example to setup cache manuallly.
This is how you can define your cache with a help of OkHTTP:
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(connectTimeOut, TimeUnit.SECONDS);
client.setReadTimeout(readTime, TimeUnit.SECONDS);
File cachePath = FuncFileDownload.getStoragePath(context, "pre");
client.setCache(new com.squareup.okhttp.Cache(cachePath, 30000000));
sPicasso = new Picasso.Builder(context)
.downloader(new OkHttpDownloader(client))
.build();
Picasso.setSingletonInstance(sPicasso);
I am working on an app with a lot of dynamic and changing content.
I pull all my data from my server when the app is loading.
As a result, nearly every activity/fragment is loading separately which will cause the user to wait a lot of time for each "page" to load individually.
My goal is to create one loading page when the app starts while being responssible for all the downloading and will disk cache all the images and info(strings) and ti pull them at the right time. (or at least to most of it)
I had the chance to use retrofit, okhttp and Picasso as a single additional library, I know though that they can work together and to be synced and that disk cacheing is available through at least two of this libraries (picasso and okhttp) I'm not sure though which one should do which part and how I can sync them together.
I will appreciate every Tip/Guidance, thanks ahead.
okhttp provides support for cache control headers. I've implemented them in an app before to provide a cache when network is flaky using this guide like so:
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(cacheDirectory, cacheSize);
client = new OkHttpClient.Builder()
.cache(cache)
.build();
As Retrofit uses okhttp internally (if you're using the latest at least), you don't configure any caching for it. Just use the okhttp client you just configured:
RestAdapter restAdapter = new RestAdapter.Builder()
.setClient(new OkClient(client))
.setServer("http://example.com")
...
.build();
Picasso automatically caches images using some default cache size limit. You can change Picasso's default, and I've found some answers here and here. You could set the cache size in the onCreate of your application:
Picasso.Builder builder = new Picasso.Builder(this);
builder.downloader(new OkHttpDownloader(this,Integer.MAX_VALUE));
Picasso picasso = builder.build();
picasso.setIndicatorsEnabled(true);
picasso.setLoggingEnabled(true);
Picasso.setSingletonInstance(picasso);
Picasso also lets you prefetch images earlier on in an app's lifecycle if you have the time to begin with (say, on a loading screen) and want to make later parts of the app load quicker. To do that, I would use the fetch method from the Picasso builder to get the images, but not insert them into any ImageViews. You can Google it too, but there's a quick answer here which explains the background behind this:
Picasso.with(getApplicationContext())
.load(url)
.fetch();
IIRC you need to make sure you fetch the same sized and transformed image as you try and retrieve later, because Picasso caches the transformed image result rather than the raw downloaded image.
Im using Picasso and okhttp to download and cache images onto the disk.
Im using the below code snippet to set a cache of 10MB to the okhttp client and using it for Picasso.
File folder = new File(context.getCacheDir(),"HomePageCache");
if (!folder.exists())
folder.mkdir();
okHttpClient.setCache(new com.squareup.okhttp.Cache(folder, 1024 * 1024 * 10));
OkHttpDownloader okHttpDownloader = new OkHttpDownloader(okHttpClient);
picasso = new com.squareup.picasso.Picasso.Builder(context).indicatorsEnabled(true).downloader(okHttpDownloader).build();
This is working perfectly most of the time caching and reloading images even when offline , but the problem is that sometimes it just clears the image cache completely.
I am checking the size of the image cache just to be sure, and it has never crossed 2 MB.
Is there any other reason why my cache is getting cleared?
Like Nikola pointed out in the comment, the cache expire header was responsible for invalidating cached images.
Hi I'm trying to understand how to use the Picasso library to cache my downloaded images, so I created a very simple app with one activity, put an ImageView on it and wrote the simplest Picasso line:
Picasso.with(this).load("http://www.estambiente.it/wp-content/uploads/2009/12/Patern_test.jpg")
.placeholder(R.drawable.holder)
.error(R.drawable.error)
.into(im);
but I wanted to see the cache indicators, so I wrote this to show them:
OkHttpClient picassoClient = new OkHttpClient();
Picasso picasso = new Picasso.Builder(this).downloader(new OkHttpDownloader(picassoClient)).build();
picasso.setIndicatorsEnabled(true);
picasso.load("http://www.estambiente.it/wp-content/uploads/2009/12/Patern_test.jpg").into(im);
this code always show the red flag (meaning the image comes from the network) and if I try to open the app while I'm not connected, the error image is shown.
what am I missing here?