OkHttp DiskLruCache java.util.NoSuchElementException

# OkHttp DiskLruCache(29064)

java.util.NoSuchElementException
1
java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:759)
2
java.util.LinkedHashMap$LinkedValueIterator.next(LinkedHashMap.java:785)
3
okhttp3.internal.cache.DiskLruCache.trimToSize(Unknown Source:18)
4
okhttp3.internal.cache.DiskLruCache$1.run(Unknown Source:25)
5
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
6
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
7
java.lang.Thread.run(Thread.java:919)

项目里边是retrofit+okhttp3 3.14.9
一开始以为是okhttp的bug,查证了一番发现没有作用,重新review代码,发现

 OkHttpClient.Builder.cache(Cache cache)

传入的cache并不是单例,也就是说,对于同一缓存目录,只能传入同一个cache对象。否则,如果Retrofit访问的url相同时,会出现多个线程处理同一个缓存文件的情况,在trimToSize的时候,出现多线程问题。
解决方案:
review代码中的调用,保证同一个retrofit对象或者同一缓存目录,使用同一个cache
代码示例

    private static Map<String,Cache> cacheHashMap =new ConcurrentHashMap<>();
    private Cache initDiskCache(String dir) {
         Cache diskCache  =null;
    	 if(cacheHashMap.get(dir)!=null){
                diskCache = cacheHashMap.get(dir);
                return diskCache;
            }
        Cache diskCache = new Cache(new File(dir), maxCacheSize);
         cacheHashMap.put(dir,diskCache);
        return diskCache;
    }
   //代码示意,同一缓存目录或者同一reftrofit保证单例
    private void buildOkhttpClient(){
     	OkHttpClient.Builder builder = new OkHttpClient.Builder();
     	//此处多为外部存储目录,需要重新看下
        builder.cache(initDiskCache(context.getFilesDir().getPath());
   }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值