Retrofit缓存设置,处理UnKnownHostException异常信息

okHttp是相当于httpURLConnection、HttpClient同一级别的网络请求方式,而现在的httpURLConnection底层也是通过okHttp来实现的。因此square公司之前出了一个新的框架:Retrofit对okHttp近一步封装。

通常我们对网络数据进行请求,联网的时候返回数据,没有网络的时候则无法请求数据。这种效果其实对很多App来说不是很令人满意的。因此,我们希望在没有网络的时候,去调用请求,可以获得历史的缓存数据,这样的话,App也会显得更加人性化,更加的有可使用性。

Retrofit刚好很好的给我们提供了设置缓存的方法。

因为Retrofit是基于okHttp的,因此,它的缓存设置需要通过okHttp来实现。

在这里,给大家两种缓存设置的方法:

1、当请求网络超时,去读取缓存数据:

	private static final int TIMEOUT_CONNECT = 5; //5秒

	static final Interceptor REWRITE_RESPONSE_INTERCEPTOR = new Interceptor() {
		@Override
		public okhttp3.Response intercept(Chain chain) throws IOException {
			//获取retrofit @headers里面的参数,参数可以自己定义,在本例我自己定义的是cache,跟@headers里面对应就可以了
			String cache = chain.request().header("cache");
			okhttp3.Response originalResponse = chain.proceed(chain.request());
			String cacheControl = originalResponse.header("Cache-Control");
			//如果cacheControl为空,就让他TIMEOUT_CONNECT秒的缓存,本例是5秒,方便观察。注意这里的cacheControl是服务器返回的
			if (cacheControl == null) {
				//如果cache没值,缓存时间为TIMEOUT_CONNECT,有的话就为cache的值
				if (cache == null || "".equals(cache)) {
					cache = TIMEOUT_CONNECT + "";
				}
				originalResponse = originalResponse.newBuilder()
						.header("Cache-Control", "public, max-age=" + cache)
						.build();
				return originalResponse;
			} else {
				return originalResponse;
			}
		}
	};


2、当网络未连接时,直接去读取缓存数据:

	private static final int TIMEOUT_DISCONNECT = 60 * 60 * 24 * 7; //7天	

static final Interceptor REWRITE_RESPONSE_INTERCEPTOR_OFFLINE = new Interceptor() {
		@Override
		public okhttp3.Response intercept(Chain chain) throws IOException {
			Request request = chain.request();
			//离线的时候为7天的缓存。
			if (JuMuApplication.isWorkingOffline()) {
				request = request.newBuilder()
						.header("Cache-Control", "public, only-if-cached, max-stale=" + TIMEOUT_DISCONNECT)
						.build();
			}
			return chain.proceed(request);
		}
	};

使用方法:

首先设置OkhttpClient,为其添加拦截器,然后在设置Retrofit即可。
private static Retrofit retrofit;
private final static int SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MiB

String cacheFile = context.getCacheDir() + "response_cache";
Cache cache = new Cache(new File(cacheFile), SIZE_OF_CACHE);
//利用okhttp实现缓存
OkHttpClient client = new OkHttpClient.Builder()
//有网络时的拦截器
.addNetworkInterceptor(RetrofitCacheStrategy.REWRITE_RESPONSE_INTERCEPTOR)
//没网络时的拦截器
.addInterceptor(RetrofitCacheStrategy.REWRITE_RESPONSE_INTERCEPTOR_OFFLINE)
.cache(cache)
.build();
retrofit = new Retrofit.Builder().client(client).baseUrl(BASE_URL).build();

关于UnKnownHostException问题解决方法:

当我们首次就去没有网络读取数据的时候,Retrofit会去缓存读取,这时Retrofit认为是有数据可以请求的,但是因为是首次,本地并没有缓存,导致了我们请求服务器的时候,报了UnKnownHostException这个异常。关于这个问题,很多人也在github上面提过,而处理的方法就是直接try catch去避免异常。
当我们用RxJava + Retrofit的时候就更加方便了,我只有在doOnError里对异常进行trycatch或者直接,添加
.onErrorResumeNext(Flowable.<T>empty());
避免所有异常即可,当然后者的方法太笼统了,可能会导致忽略了其他关键问题。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值