【问题标题】:Got this error with retrofit2 & OkHttp3. Unable to resolve host "<host-name>": No address associated with hostname使用改造 2 和 OkHttp3 出现此错误。无法解析主机“<主机名>”:没有与主机名关联的地址
【发布时间】:2016-11-02 01:15:06
【问题描述】:

我正在使用改造 2 和 OkHttp3 从服务器请求数据。我刚刚添加了一个离线缓存代码,但它没有按预期工作。我收到错误“无法解析主机“”:没有与主机名关联的地址。”

当它试图从缓存中获取检索数据时会发生这种情况(当没有互联网连接时)。下面是一个代码sn-p。

public static Interceptor provideCacheInterceptor() {
    return new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());

            // re-write response header to force use of cache
            CacheControl cacheControl = new CacheControl.Builder()
                    .maxAge(2, TimeUnit.MINUTES)
                    .build();

            return response.newBuilder()
                    .header(CACHE_CONTROL, cacheControl.toString())
                    .build();
        }
    };
}

public static Interceptor provideOfflineCacheInterceptor() {
    return new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            if (!hasNetwork) {
                CacheControl cacheControl = new CacheControl.Builder()
                        .onlyIfCached()
                        .maxStale(7, TimeUnit.DAYS)
                        .build();

                request = request.newBuilder()
                        .removeHeader("Pragma")
                        .cacheControl(cacheControl)
                        .build();
            }

            return chain.proceed(request);
        }
    };
}

private static Cache provideCache() {
    Cache cache = null;
    try {
        cache = new Cache(new File(AdeptAndroid.getInstance().getCacheDir(), "http-cache"),
                10 * 1024 * 1024); // 10 MB
    } catch (Exception e) {
        Log.d("Test", "Could not create Cache!");
    }
    return cache;
}

最后一个结合所有这些的方法就在这里。

private static OkHttpClient provideOkHttpClient() {
    return new OkHttpClient.Builder()
            .addInterceptor(provideHttpLoggingInterceptor())
            .addInterceptor(provideOfflineCacheInterceptor())
            .addNetworkInterceptor(provideCacheInterceptor())
            .cache(provideCache())
            .build();
}

【问题讨论】:

  • 以这种方式设置标题(正好是 50000)解决了这个问题。 .header("Cache-Control", String.format("max-age=%d", 50000))
  • @WaqarYounis 感谢您的回复,但它也不起作用。
  • 您解决了这个问题吗?使用 GCM 从后台唤醒应用时遇到此问题。
  • @android_griezmann 你有没有找到任何解决方法,导致遇到同样的问题并且无法通过它。
  • @dexmorgan 不!很抱歉这么说,但到目前为止还没有找到任何解决方案。

标签: android okhttp retrofit2 offline-caching okhttp3


【解决方案1】:

我在使用 kotlin 的项目中遇到了同样的错误,我将其修复如下:

client.addInterceptor(provideOfflineCacheInterceptor(context))
client.addNetworkInterceptor(provideCacheInterceptor(context))

private fun provideOfflineCacheInterceptor(context: Context): Interceptor {
        return Interceptor { chain ->
            var request = chain.request()
            var cacheHeaderValue = if (!hasNetwork(context)!!){
                    "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 1
                } else {
                    "public, max-age=" + 5
                }
            request = request.newBuilder().header("Cache-Control", cacheHeaderValue).build()
            chain.proceed(request)
        }
    }

    private fun provideCacheInterceptor(context: Context): Interceptor {
        return Interceptor { chain ->
            val request = chain.request()
            var cacheHeaderValue = if (!hasNetwork(context)!!){
                    "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 1
                } else {
                    "public, max-age=" + 5
                }
            //request = request.newBuilder().build()
            val response = chain.proceed(request)
            response.newBuilder()
                    .removeHeader("Pragma")
                    .removeHeader("Cache-Control")
                    .header("Cache-Control", cacheHeaderValue)
                    .build()
        }
    }

【讨论】:

    【解决方案2】:

    您的服务器响应有一个“Pragma: no-cache”标头。您应该在响应拦截器而不是请求拦截器中删除此标头。

    在您当前的代码中,您已将其从请求拦截器中删除。

    您的provideCacheInterceptor() 应如下所示:

    public static Interceptor provideCacheInterceptor() {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Response response = chain.proceed(chain.request());
    
                // re-write response header to force use of cache
                CacheControl cacheControl = new CacheControl.Builder()
                       .maxAge(2, TimeUnit.MINUTES)
                       .build();
    
               return response.newBuilder()
                        .header(CACHE_CONTROL, cacheControl.toString())
                        .removeHeader("Pragma")
                        .build();
            }
        };
    }
    

    【讨论】:

    【解决方案3】:

    请在模拟器上的清单文件权限关闭飞行模式中检查您的网络“打开”

    【讨论】:

      【解决方案4】:

      当尝试访问连接网络上不可用的主机名时会发生这种情况。检查您是否可以通过设备的网络浏览器访问此 URL。如果不是:那是你的问题。

      【讨论】:

        【解决方案5】:

        对我来说,错误是因为模拟器中没有互联网连接而引发的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-01-20
          • 2015-06-24
          • 1970-01-01
          • 2017-12-04
          • 2018-12-04
          • 2021-10-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多