1

When I try to download image from disk with very slow connection (GPRS), it's very long (about 10min) and I get Socket exception before get image from DISK.

compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.squareup.okhttp:okhttp:2.4.0'

OkHttpClient client = new OkHttpClient();
    client.setCache(new Cache(context.getApplicationContext().getCacheDir(), Integer.MAX_VALUE));
    client.setConnectTimeout(5, TimeUnit.SECONDS); // connect timeout
    client.setReadTimeout(15, TimeUnit.SECONDS);    // socket timeout
    Picasso.Builder builder = new Picasso.Builder(this);
    builder.downloader(new OkHttpDownloader(client));
    Picasso built = builder.build();
    built.setIndicatorsEnabled(BuildConfig.DEBUG);
    built.setLoggingEnabled(BuildConfig.DEBUG);
    Picasso.setSingletonInstance(built);

enter image description here

enter image description here

Thanks in advance

PS: Sorry about my bad english

Louis
  • 406
  • 6
  • 13
  • Your server from where you are downloading the image is resetting the connection. Picasso has to download the image once and then it will cache onto the disk cache. Here the first attempt itself is getting rejected due to the slow connection. – Kushan Jul 15 '16 at 13:22
  • try increasing the connection timeout value to say 15 mins – Kushan Jul 15 '16 at 13:23
  • @Kushan Thanks for you answer but i already download image the first time. This error appear the second time, when I try to get image (already download) from disk. – Louis Jul 15 '16 at 13:32
  • see https://newfivefour.com/android-okhttp-retrofit-using-cache.html for another example :) – Kushan Jul 15 '16 at 14:03

2 Answers2

2

I used a custom Picasso with my own OKHTTP3 downloader and i set a disk cache timeout as 6000s (100mins lol). Tinker around as you need with both LRU->memory and Disk cache -> Cache

package com.example.project.recommendedapp;


import android.content.Context;
import android.util.Log;

import com.jakewharton.picasso.OkHttp3Downloader;
import com.squareup.picasso.LruCache;
import com.squareup.picasso.Picasso;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.OkHttpClient;

//Singleton Class for Picasso Downloading, Caching and Displaying Images Library
public class PicassoSingleton {

private static Picasso mInstance;
private static long mDiskCacheSize = 50*1024*1024; //Disk Cache limit 50mb

//private static int mMemoryCacheSize = 50*1024*1024; //Memory Cache 50mb, not currently using this. Using default implementation

private static OkHttpClient mOkHttp3Client; //OK Http Client for downloading
private static OkHttp3Downloader okHttp3Downloader;
private static Cache diskCache;
private static LruCache lruCache;//not using it currently


public static synchronized Picasso getSharedInstance(Context context)
{
    if(mInstance == null) {
        if (context != null) {
            //Create disk cache folder if does not exist
            File cache = new File(context.getApplicationContext().getCacheDir(), "picasso_cache");
            if (!cache.exists()) {
                cache.mkdirs();
            }

            diskCache = new Cache(cache, mDiskCacheSize);
            //lruCache = new LruCache(mMemoryCacheSize);//not going to be using it, using default memory cache currently
            lruCache = new LruCache(context); // This is the default lrucache for picasso-> calculates and sets memory cache by itself

            //Create OK Http Client with retry enabled, timeout and disk cache
            mOkHttp3Client = new OkHttpClient.Builder().cache(diskCache).connectTimeout(6000, TimeUnit.SECONDS).build();  //100 min cache timeout



            //For better performence in Memory use set memoryCache(Cache.NONE) in this builder (If needed)
            mInstance = new Picasso.Builder(context).memoryCache(lruCache).downloader(new OkHttp3Downloader(mOkHttp3Client)).indicatorsEnabled(true).build();

        }
    }
    return mInstance;
}

public static void deletePicassoInstance()
{
    mInstance = null;
}

public static void clearLRUCache()
{
    if(lruCache!=null) {
        lruCache.clear();
        Log.d("FragmentCreate","clearing LRU cache");
    }

    lruCache = null;

}

public static void clearDiskCache(){
    try {
        if(diskCache!=null) {
            diskCache.evictAll();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    diskCache = null;

}
}
Kushan
  • 5,855
  • 3
  • 31
  • 45
0

It is possible that your server sent a file without proper cache headers. In this case, your OKHTTP will not cache the image.

Picasso doesn't have a disk cache. It delegates to whatever HTTP client you are using for that functionality (relying on HTTP cache semantics for cache control).

Using Picasso with custom disk cache

Thus the next time, it will retry a download. I have seen this happen with any images download from DropBox shared links.

The caching happens of the http response not the image, so if the response does not have proper headers sent by the server, it will not be cached. Check if this is the case. Try using another source of image to test.

Community
  • 1
  • 1
Kushan
  • 5,855
  • 3
  • 31
  • 45
  • http://stackoverflow.com/questions/35806571/picasso-doesnt-cache-image-on-disk -> see explanation here, its the same issue – Kushan Jul 15 '16 at 13:38
  • When i try with fast connection, it's work correctly and the debug indicator is blue (from disk). – Louis Jul 15 '16 at 13:39
  • might be possible that the httpresponse timedout. As i said the caching happens on the ResponseCache or OkResponseCache. If the response cache header times out due to slow connection, it will get evicted from the disk cache – Kushan Jul 15 '16 at 13:41
  • Thanks for your link but it's not the same issue. When i try with fast connection it's works. After wait about 10min with slow connection, it's work too with exception (you can see my second image and time) – Louis Jul 15 '16 at 13:42
  • Before get image from disk, i think picasso check if image is already the same as the server. Can i disable that or set a timeout ? (i tried setConnectTimeout ou setReadTimeout) – Louis Jul 15 '16 at 13:46
  • No the order is Memory -> Disk -> last case network. There is a way to addHeaders to your requests. Not sure exactly how to for the cache one. See this for an idea : http://stackoverflow.com/questions/24273783/android-picasso-library-how-to-add-authentication-headers – Kushan Jul 15 '16 at 13:52