0

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.

Roee
  • 1,155
  • 3
  • 15
  • 24

1 Answers1

2

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.

Community
  • 1
  • 1
roarster
  • 4,058
  • 2
  • 25
  • 38
  • 1
    Please don't just link all over the place (especially articles on external sites). Put the relevant parts of those external sources into your answer as quotes. This way, the answer stays valid even if the external pages go down. – Lukas Knuth May 08 '16 at 11:31
  • Thank you! seems like it's exactly what I needed. I will start read it now. – Roee May 08 '16 at 11:49
  • 1
    @LukasKnuth right, that was on my mind when I was writing the answer, so I'll update it, but all of the parts of the question can be answered by different SO answers. It's not a duplicate because there's no other question that asks the same questions together, so what's the harm in answering with a bunch of SO links? If SO is down and so the links are down, you can't even access this question in the first place... – roarster May 08 '16 at 13:05
  • @roarster questions can be deleted (even if the user deletes his own account), so there's that. Usually, if it's a long answer then yes, the link is fine. If it boils down to two sentences or 5 lines of code quote them and put the link as the source. – Lukas Knuth May 09 '16 at 10:52