2015-09-16 5 views
10

मैं Retrofit 1.9.0 और OkHtttp 2.5.0 के साथ कैश को कॉन्फ़िगर करने का प्रयास कर रहा हूं।रेट्रोफिट + आरएक्सजेवा प्रतिक्रियाओं को कैश करने में विफल रहता है, संदिग्ध प्रतिक्रिया शीर्षलेख

यहाँ है कैसे मैं अपने RestAdapter के लिए OkHttpClient प्रदान करते हैं:

@Provides 
@Singleton 
public OkHttpClient provideOkHttpClient() { 
    OkHttpClient okHttpClient = new OkHttpClient(); 
    okHttpClient.setConnectTimeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); 
    okHttpClient.setReadTimeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); 
    okHttpClient.setWriteTimeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); 

    File cacheDir = new File(context.getCacheDir(), "http"); 
    final Cache cache = new Cache(cacheDir, DISK_CACHE_SIZE_IN_BYTES); 
    okHttpClient.setCache(cache); 

    okHttpClient.interceptors().add(new Interceptor() { 
     @Override 
     public Response intercept(Chain chain) throws IOException { 

      Response response = chain.proceed(request); 
      Response finalResponse = response.newBuilder() 
        .header("Cache-Control", String.format("public, max-stale=%d", 604800)) 
        .build(); 

      Log.d("OkHttp", finalResponse.toString()); 
      Log.d("OkHttp Headers", finalResponse.headers().toString()); 
      return finalResponse; 
     } 
    }); 

    return okHttpClient; 
} 

मैं RestAdapter.Builder पर setClient भूल नहीं की। यह भी सुनिश्चित किया गया है कि, मैं वास्तव में इस क्लाइंट सेट के साथ RestAdapter का उदाहरण उपयोग कर रहा हूं।

यहां तक ​​कि जांच की गई है कि फाइलें "http" फ़ोल्डर के अंतर्गत बनाई गई हैं या नहीं। वो हैं।

हालांकि बाद मैं वाईफ़ाई की बारी और अपनी स्क्रीन को फिर से लोड मैं इस संदेश के साथ Observable endpoint की OnError कॉलबैक में अंत:

retrofit.RetrofitError: failed to connect to /10.40.31.12 (port 8888) after 10000ms: connect failed: ENETUNREACH (Network is unreachable) 

अस्वीकरण: मैं शायद यह है कि अंतिम Observable 5 दूसरों से संयुक्त है उल्लेख करना चाहिए, रास्ते पर flatMap और zip के साथ।

+0

संभावित डुप्लिकेट [ऑफ़लाइन होने पर ओकेएचटीपी उपयोग कैश डेटा के साथ रेट्रोफिट कर सकते हैं] (http://stackoverflow.com/questions/23429046/can-retrofit-with-okhttp-use-cache-data-when-offline) – njzk2

उत्तर

3

मुझे लगता है कि मेरे पास जवाब है। छोटा एक है: "अगर सर्वर प्रतिक्रिया में नो-कैश हेडर भेजता है तो नहीं किया जा सकता"।

यदि आप लंबा चाहते हैं, तो विवरण नीचे दिए गए हैं।

मैंने 2 बैकएंड की तुलना में नमूना ऐप बनाया है। चलो उन्हें बैकएंड एक कहते हैं, और बैकएंड बी ए मेरे लिए परेशानी पैदा तो मैं बी पर जांच करने के

एक रिटर्न CacheControl = "no-cache, no-transform, max-age=0"

बी रिटर्न Cache-Control = „public" प्रतिक्रिया हेडर

मैं एक ही सेटअप किया था फैसला किया है दे रहा था दोनों बैकएंड के लिए, सिर्फ अलग यूआरएल।

private void buildApi() { 
     Gson gson = new GsonBuilder().create(); 

     OkHttpClient okHttpClient = new OkHttpClient(); 
     okHttpClient.setConnectTimeout(10, TimeUnit.SECONDS); 

     File cacheDir = new File(getCacheDir(), "http"); 
     final Cache cache = new Cache(cacheDir, 1000000 * 10); 
     okHttpClient.setCache(cache); 

     okHttpClient.interceptors().add(new Interceptor() { 
      @Override 
      public Response intercept(Chain chain) throws IOException { 
       Request request = chain.request(); 
       Log.d("OkHttp REQUEST", request.toString()); 
       Log.d("OkHttp REQUEST Headers", request.headers().toString()); 

       Response response = chain.proceed(request); 
       response = response.newBuilder() 
         .header("Cache-Control", String.format("public, max-age=%d, max-stale=%d", 60, RESPONSE_CACHE_LIFESPAN_IN_SECONDS)) 
         .build(); 

       Log.d("OkHttp RESPONSE", response.toString()); 
       Log.d("OkHttp RESPONSE Headers", response.headers().toString()); 
       return response; 
      } 
     }); 

     RestAdapter.Builder builder = new RestAdapter.Builder() 
       .setConverter(new StringGsonConverter(gson)) 
       .setClient(new OkClient(okHttpClient)) 
       .setRequestInterceptor(new RequestInterceptor() { 
        @Override 
        public void intercept(RequestFacade request) { 

         if (isNetworkAvailable()) { 
          request.addHeader("Cache-Control", "public, max-age=" + 60); 
         } else { 
          request.addHeader("Cache-Control", "public, only-if-cached, max-stale=" + RESPONSE_CACHE_LIFESPAN_IN_SECONDS); 
         } 
        } 
       }); 

     builder.setEndpoint("http://this.is.under.vpn.so.wont.work.anyway/api"); 
     A_API = builder.build().create(AApi.class); 

     builder.setEndpoint("http://collector-prod-server.elasticbeanstalk.com/api"); 
     B_API = builder.build().create(BApi.class); 
    } 

दोनों कॉल, फिर वाईफ़ाई अक्षम कर दिया गया। कैश बी के लिए ठीक काम करता है, लेकिन एक 504 Unsatisfiable Request (only-if-cached)

ऐसा लगता है कि ओवरराइटिंग हेडर उस मामले में मदद नहीं करेंगे।

2

आपको Response के बजाय अपने Request को फिर से लिखना चाहिए। संदर्भ के लिए, rewriting requests पर दस्तावेज़ देखें। यदि आप चाहें तो अपने स्वयं के शीर्षलेख के निर्माण के बजाय CacheControl कक्षा का भी उपयोग कर सकते हैं। आपके इंटरसेप्टर को कुछ दिखना चाहिए -

okHttpClient.interceptors().add(new Interceptor() { 
    @Override 
    public Response intercept(Chain chain) throws IOException { 

    Request request = chain.request(); 
    Request cachedRequest = request.newBuilder() 
     .cacheControl(new CacheControl.Builder() 
      .maxStale(7, TimeUnit.DAYS) 
      .build()) 
     .build(); 

    return chain.proceed(cachedRequest); 
    } 
}); 
+0

दुर्भाग्यवश यह –

+0

काम नहीं करता हां, यह काम नहीं करता है। – amj

संबंधित मुद्दे