Nicht in der Lage, Daten aus dem Cache zu laden okHttp & retrofit

Hier ist mein Code, wo ich aq nenne und auch Cache für okhttp mit Retrofit definiere:

public class DemoPresenter { DemoView vDemoView; private Context mContext; public DemoPresenter(Context mcontext, DemoView vDemoView) { this.vDemoView = vDemoView; this.mContext = mcontext; } public void callAllProduct() { if (vDemoView != null) { vDemoView.showProductProgressBar(); } OkHttpClient okHttpClient = new OkHttpClient.Builder() .cache(new Cache(mContext.getCacheDir(), 10 * 1024 * 1024)) // 10 MB .addInterceptor(new Interceptor() { @Override public okhttp3.Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (BasicUtility.isInternet(mContext)) { request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build(); } else { request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 7).build(); } return chain.proceed(request); } }) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("www.xyz.com/data/") .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient) .build(); AllApi productApiService = retrofit.create(AllApi.class); Call<ProductData> call = productApiService.getProduct(); try { call.enqueue(new Callback<ProductData>() { @Override public void onResponse(Call<ProductData> call, Response<ProductData> response) { ArrayList<Product> alproducts = new ArrayList<>(); try { alproducts = response.body().getProductData(); onSuccess(alproducts); } catch (Exception e) { } } @Override public void onFailure(Call<ProductData> call, Throwable t) { } }); } catch (Exception e) { } } private void onSuccess(ArrayList<Product> alproducts) { if (vDemoView != null) { vDemoView.hideProductProgressBar(); vDemoView.onProductSuccess(alproducts); } } } 

Jetzt von meiner Haupttätigkeit nenne ich diese Moderatorin:

  • Verständnis von Keystore, Zertifikaten und Alias
  • Wie man aufwacht Android Wear, wenn es im Schlafmodus ist?
  • Überwachung der Netzwerkaktivität in einer HTML5 iPhone / Android App?
  • Android-Bild sehen Schwerkraft
  • Filter LogCat, um nur die Nachrichten von My Application in Android zu erhalten?
  • Wie kann ich hinzufügen. So Dateien zu einem Android-Bibliotheksprojekt mit gradle 0.7+
  •  DemoPresenter mDemoPresenter = new DemoPresenter(getApplicationContext(),this); mDemoPresenter.callAllProduct(); 

    Nun, wenn ich diese Aktivität mit Internet-Konnektivität ausführen, dann funktioniert es gut, aber wenn ich Internet getrennt und diese Aktivität wieder ausführen, dann wird es nicht laden Daten aus dem Cache.

    Wie kann ich diese Daten aus dem Cache laden, wenn es kein Internet gibt?

  • Wie installiere ich das Android Studio 2.2 CMake Paket / Tool?
  • Android wear - eclipse: nicht erkannt unterstützen Bibliothek
  • Wie man die Android-Designer-Ansicht in Intellij Idea12 verkleinern kann?
  • Wie kann man den Oberflächenhalter löschen, wenn der Mediaplayer fertig ist?
  • Welche Dateien sollte ich zu SVN ignorieren in einem Projekt mit Android Studio hinzufügen
  • GetSupportActionBar () gibt null mit Robolectric zurück
  • 4 Solutions collect form web for “Nicht in der Lage, Daten aus dem Cache zu laden okHttp & retrofit”

    Sie können das ausprobieren:

     public class DemoPresenter { DemoView vDemoView; private Context mContext; private static final String CACHE_CONTROL = "Cache-Control"; private static final String TAG = DemoPresenter.class.getName(); public DemoPresenter(Context mcontext, DemoView vDemoView) { this.vDemoView = vDemoView; this.mContext = mcontext; } public void callAllProduct() { if (vDemoView != null) { vDemoView.showProductProgressBar(); } OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor( provideOfflineCacheInterceptor() ) .addNetworkInterceptor( provideCacheInterceptor() ) .cache( provideCache() ) .build(); /* OkHttpClient okHttpClient = new OkHttpClient.Builder() .cache(new Cache(mContext.getCacheDir(), 10 * 1024 * 1024)) // 10 MB .addInterceptor(new Interceptor() { @Override public okhttp3.Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (BasicUtility.isInternet(mContext)) { request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build(); } else { request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 7).build(); } return chain.proceed(request); } }) .build();*/ Retrofit retrofit = new Retrofit.Builder() .baseUrl("www.xyz.com/data/") .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient) .build(); AllApi productApiService = retrofit.create(AllApi.class); Call<ProductData> call = productApiService.getProduct(); try { call.enqueue(new Callback<ProductData>() { @Override public void onResponse(Call<ProductData> call, Response<ProductData> response) { ArrayList<Product> alproducts = new ArrayList<>(); try { alproducts = response.body().getProductData(); onSuccess(alproducts); } catch (Exception e) { } } @Override public void onFailure(Call<ProductData> call, Throwable t) { } }); } catch (Exception e) { } } private void onSuccess(ArrayList<Product> alproducts) { if (vDemoView != null) { vDemoView.hideProductProgressBar(); vDemoView.onProductSuccess(alproducts); } } public Interceptor provideOfflineCacheInterceptor () { return new Interceptor() { @Override public Response intercept (Chain chain) throws IOException { Request request = chain.request(); if (BasicUtility.isInternet(mContext)) { CacheControl cacheControl = new CacheControl.Builder() .maxStale( 7, TimeUnit.DAYS ) .build(); request = request.newBuilder() .cacheControl( cacheControl ) .build(); } return chain.proceed( request ); } }; } 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( 1, TimeUnit.MINUTES ) .build(); return response.newBuilder() .header( CACHE_CONTROL, cacheControl.toString() ) .build(); } }; } private Cache provideCache () { Cache cache = null; try { cache = new Cache( new File( mContext.getCacheDir(), "http-cache" ), 10 * 1024 * 1024 ); // 10 MB } catch (Exception e) { Log.e(TAG, "Could not create Cache!"); } return cache; } } 

    Ich arbeite gut für mich.

    Mögliche Fehler: Weil du alles in callAllProduct () gelegt hast, so dass du jedes Mal einen neuen okHttpClient und einen neuen Cache okHttpClient , bist du deinen alten Cache nicht wiederverwendbar. Sie funktionieren abhängig von callAllProduct, callAllProduct hängt von neuem okHttpClient ab, okHttpCient ist Funktionalität abhängig vom neuen Cache. Putting okHttpClient außerhalb deines callAllProduct () callAllProduct macht dich auf den gleichen alten okHttpClient in jedem callAllProduct-Aufruf ab. Versuche es einfach, obwohl ich auch nicht weiß, wie die Retrofit interne Caching funktioniert. Wenn es noch nicht funktioniert, entschuldige ich mich für meine nicht funktionierende Idee, aber ich verspreche es, ich werde dir wieder helfen.

    Die Idee lautet: Jedes Mal, wenn du callAllProduct () nennst, benutzt du die okHttpClient-Anforderung, um die API-Ebene neu zu implementieren. Retrofit-Schicht prüft, ob es bereits die Daten gespeichert hat, die mit Ihrem okHttpClient verbunden sind oder nicht? Jede neue okHttpClient-Instanz bedeutet jede neue http-Anfrage, also jede neue ID, die sie für das Zwischenspeichern von Daten erzeugt. Der alte Cache wird nie verwendet, weil jedes Mal, wenn Sie eine neue Instanz von okHttpClient verwenden. Retrofit sieht keine zugehörige ID mit deiner okHttpRequest-Instanz, also leitet die Anforderung an das Internet weiter. Web-Server-Antworten mit Daten. Nun, Retrofit schafft neue ID für den Cache für die erfolgreiche Ok HTTP Client Anfrage. Aber wenn du jedesmal einen neuen okHttpClient benutzt hast, dann ist die alte Cache-ID nie benutzt, also passiert es immer Cache-Miss immer.

    Dieser unten genannte Code sollte außerhalb callAllProduct() Körper sein

      int cacheSize = 10 * 1024 * 1024; /* 10 MB. Also try increasing cache size */ public static Cache myCache = new Cache(getCacheDir(), cacheSize); OkHttpClient okHttpClient = new OkHttpClient.Builder() .cache(myCache) // 10 MB .addInterceptor(new Interceptor() { @Override public okhttp3.Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (BasicUtility.isInternet(mContext)) { request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build(); } else { request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 7).build(); } return chain.proceed(request); } }) .build(); 

    Nun wird Ihr callAllProduct () wie unten gezeigt:. Dies garantiert Ihnen den gleichen okHttpClient alle, wenn Sie callAllProduct () anrufen.

     public void callAllProduct() { if (vDemoView != null) { vDemoView.showProductProgressBar(); } Retrofit retrofit = new Retrofit.Builder() .baseUrl("www.xyz.com/data/") .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient) .build(); AllApi productApiService = retrofit.create(AllApi.class); Call<ProductData> call = productApiService.getProduct(); try { call.enqueue(new Callback<ProductData>() { @Override public void onResponse(Call<ProductData> call, Response<ProductData> response) { ArrayList<Product> alproducts = new ArrayList<>(); try { alproducts = response.body().getProductData(); onSuccess(alproducts); } catch (Exception e) { } } @Override public void onFailure(Call<ProductData> call, Throwable t) { } }); } catch (Exception e) { } } 

    Ihr Interceptor sollte auf Konnektivität überprüfen und CacheHeaderValue entsprechend setzen. In diesem Beispiel verwendet es eine Methode isNetworkAvailable, um dies zu tun:

     okClient.interceptors().add( new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); String cacheHeaderValue = isNetworkAvailable(context) ? "public, max-age=2419200" : "public, only-if-cached, max-stale=2419200" ; Request request = originalRequest.newBuilder().build(); Response response = chain.proceed(request); return response.newBuilder() .removeHeader("Pragma") .removeHeader("Cache-Control") .header("Cache-Control", cacheHeaderValue) .build(); } } ); okClient.networkInterceptors().add( new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); String cacheHeaderValue = isNetworkAvailable(context) ? "public, max-age=2419200" : "public, only-if-cached, max-stale=2419200" ; Request request = originalRequest.newBuilder().build(); Response response = chain.proceed(request); return response.newBuilder() .removeHeader("Pragma") .removeHeader("Cache-Control") .header("Cache-Control", cacheHeaderValue) .build(); } } ); 

    Sie müssen einen Offline-Cache-Interceptor für OkHttp hinzufügen, um die Antwort für die Offline-Verwendung zwischenzuspeichern. Sie können auch Daten für eine Minute zwischenspeichern und wenn die Anforderung innerhalb einer Minute gesendet wird, werden die Daten aus dem Cache verwendet.

     /** * Interceptor to cache data and maintain it for four weeks. * * If the device is offline, stale (at most four weeks old) * response is fetched from the cache. */ private static class OfflineResponseCacheInterceptor implements Interceptor { @Override public okhttp3.Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (!UtilityMethods.isNetworkAvailable()) { request = request.newBuilder() .header("Cache-Control", "public, only-if-cached, max-stale=" + 2419200) .build(); } return chain.proceed(request); } } 

    Befolgen Sie dieses Tutorial, um mehr über das Zwischenspeichern von Daten zu erfahren – https://krtkush.github.io/2016/06/01/caching-using-okhttp-part-1.html Auch diese Stack Overflow-Antwort kann mit OKHttp mit Cache-Daten umgehen, wenn offline

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.