2017-01-18 10 views
11

क्या यह पता लगाने का कोई तरीका है कि एक रेट्रोफिट प्रतिक्रिया कॉन्फ़िगर की गई ओकेएचटीपी कैश से आती है या लाइव प्रतिक्रिया है?पता लगाएं कि ओकेएचटीपी प्रतिक्रिया कैश से है (रेट्रोफिट के साथ)

क्लाइंट परिभाषा:

Cache cache = new Cache(getCacheDirectory(context), 1024 * 1024 * 10); 
OkHttpClient okHttpClient = new OkHttpClient.Builder() 
      .cache(cache) 
      .build(); 

एपीआई परिभाषा:

@GET("/object") 
Observable<Result<SomeObject>> getSomeObject(); 

उदाहरण कॉल:

RetroApi retroApi = new Retrofit.Builder() 
      .client(okHttpClient) 
      .baseUrl(baseUrl) 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
      .addConverterFactory(GsonConverterFactory.create()) 
      .build() 
      .create(RetroApi.class); 

result = retroApi.getSomeObject().subscribe((Result<SomeObject> someObjectResult) -> { 
    isFromCache(someObjectResult); // ??? 
}); 

उत्तर

13

किसी भी समय आप एक okhttp3.Response (retrofit2.Response.raw()) है, तो आप देख सकते हैं कि प्रतिक्रिया कैश से है।

जेसी विल्सन के शब्दों में:

कुछ कॉम्बो रहे हैं।

.networkResponse()केवल - आपका अनुरोध विशेष रूप से नेटवर्क से परोसा गया था।

.cacheResponse()केवल - आपका अनुरोध विशेष रूप से कैश से परोसा जाता था।

.networkResponse() और .cacheResponse() - आपका अनुरोध एक सशर्त जीईटी था, इसलिए शीर्षलेख नेटवर्क से हैं और शरीर कैश से है।

तो अपने उदाहरण के लिए, isFromCache विधि दिखाई देगा:

boolean isFromCache(Result<?> result) { 
    return result.response().raw().networkResponse() == null; 
} 
+0

क्या यह उद्धरण किसी बात या किसी अन्य ऑनलाइन संसाधन से आता है? यदि हां, तो क्या आप एक लिंक प्रदान कर सकते हैं? – user2340612

+0

'result.response() कच्चे()। CacheResponse()! = Null' की जांच करना वास्तव में बेहतर है। यदि ग्राहक कैश किए गए प्रतिक्रिया को फिर से मान्य करता है और 304 प्राप्त करता है, तो 'नेटवर्क रेस्पॉन्स()' और 'कैश रिस्पॉन्स()' दोनों गैर-शून्य होंगे। – apottere

+0

हां, अर्थशास्त्र के आधार पर और आपका वांछित ऐप व्यवहार क्या है। –

8

समाधान 1:

okhttp3.Response.cacheResponse() का उपयोग करके आप जांच सकते हैं कि कैश से प्रतिक्रिया प्राप्त हुई थी:

कैश से प्राप्त कच्ची प्रतिक्रिया देता है। अगर यह प्रतिक्रिया कैश

का उपयोग नहीं किया अपने पुराना वापस रिस्पांस से कच्चे OkHttp प्रतिक्रिया obect .raw() का उपयोग प्राप्त करने के लिए अशक्त हो जाएगा। यानी .:

public boolean isFromCache(Result<?> retroResult) { 
    return retroResult.response().raw().cacheResponse() != null; 
} 

समाधान 2:

आप new OkHttpClient.Builder().addInterceptor(...) के माध्यम से OkHttp ग्राहक के लिए एक इंटरसेप्टर जोड़ सकते हैं। इस इंटरसेप्टर में chain.proceed(chain.request) के माध्यम से प्रतिक्रिया पुनर्प्राप्त करें। फिर क्रमशः Response.networkResponse() का उपयोग यह निर्धारित करने के लिए करें कि प्रतिक्रिया कहां से आई थी।

पूर्ण कोड:

new OkHttpClient.Builder().addInterceptor(chain -> { 
     Response response = chain.proceed(chain.request()); 
     if (response.cacheControl() != null) { 
      // from cache 
     } else if (response.networkResponse() != null) { 
      // from network 
     } 
     return response; 
}); 
+2

यह हमेशा संकेत करता है कि प्रतिक्रिया कैश से आती है! भले ही मैं एप्लिकेशन को अनइंस्टॉल कर दूं! – Fakher

+1

यह काम नहीं कर रहा है –

+1

हमेशा प्रतिक्रिया दिखा रहा है कैश –

1
if (response.raw().cacheResponse() != null) { 
    // true: response was served from cache 
} 

if (response.raw().networkResponse() != null) { 
    // true: response was served from network/server 
} 

लेकिन मैं अगर अपने networkResponse रिक्त है, एक बार के बाद से अनुरोध कैश किया गया है और आप की जाँच करने के सुझाव एक नेटवर्क रेस्पॉन्स भी, स्ट्रीम से आपकी प्रतिक्रिया पारित होती है नेटवर्क से है और कैश नहीं है (अधिकतम कैस्ट कंट्रोल पर निर्दिष्ट हो सकता है)। तो जांचें कि नेटवर्क रेस्पॉन्स शून्य नहीं है, अगर शून्य और आपके कैश रिस्पॉन्स शून्य नहीं है, प्रतिक्रिया कैश से अन्यथा विपरीत है।

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