【问题标题】:Picasso SocketException毕加索套接字异常
【发布时间】:2016-11-18 16:59:54
【问题描述】:

当我尝试以非常慢的连接 (GPRS) 从磁盘下载图像时,它很长(大约 10 分钟),并且在从磁盘获取图像之前出现 Socket 异常。

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);

提前致谢

PS: 对不起我的英语不好

【问题讨论】:

  • 您从中下载图像的服务器正在重置连接。 Picasso 必须下载一次图像,然后它将缓存到磁盘缓存中。由于连接速度慢,第一次尝试本身被拒绝。
  • 尝试将连接超时值增加到 15 分钟
  • @Kushan 谢谢你的回答,但我已经第一次下载了图像。当我尝试从磁盘获取图像(已经下载)时,第二次出现此错误。

标签: android picasso


【解决方案1】:

我使用自定义 Picasso 和我自己的 OKHTTP3 下载器,并将磁盘缓存超时设置为 6000 秒(100 分钟哈哈)。根据需要使用 LRU-> 内存和磁盘缓存 -> 缓存

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;

}
}

【讨论】:

  • 你可以设置 setReadTimeout(xyz, TimeUnit.SECONDS);还有
  • 感谢您的详细解答
【解决方案2】:

您的服务器发送的文件可能没有正确的缓存标头。在这种情况下,您的 OKHTTP 不会缓存图像。

毕加索没有磁盘缓存。它委托给您用于该功能的任何 HTTP 客户端(依赖于 HTTP 缓存语义进行缓存控制)。

Using Picasso with custom disk cache

因此,下一次,它将重试下载。我已经看到从 DropBox 共享链接下载的任何图像都会发生这种情况。

缓存发生在http响应而不是图像,因此如果响应没有服务器发送的正确标头,它将不会被缓存。检查是否是这种情况。尝试使用其他图片来源进行测试。

【讨论】:

  • stackoverflow.com/questions/35806571/… -> 看这里的解释,同样的问题
  • 当我尝试快速连接时,它工作正常并且调试指示器为蓝色(来自磁盘)。
  • 可能是 httpresponse 超时。正如我所说,缓存发生在 ResponseCache 或 OkResponseCache 上。如果响应缓存头部由于连接慢而超时,它将被从磁盘缓存中逐出
  • 感谢您的链接,但这不是同一个问题。当我尝试快速连接时,它可以工作。在连接缓慢的情况下等待大约 10 分钟后,它也可以正常工作(你可以看到我的第二张图片和时间)
  • 在从磁盘获取图像之前,我认为毕加索检查图像是否已经与服务器相同。我可以禁用它或设置超时吗? (我试过 setConnectTimeout 或 setReadTimeout)
猜你喜欢
  • 2016-06-20
  • 2023-04-09
  • 2011-05-28
  • 2011-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多