Ich versuche, HTTP-Antworten von meiner Firma API zwischenzuspeichern, aber es sieht aus wie die App nicht das Cache-Verzeichnis zugreifen kann:Caching Fehler mit Retrofit 2 und 3 okhttp
verknüpftW/System.err: Entfernen fehlgeschlagen: ENOENT (Keine solche Datei oder das Verzeichnis): /data/user/0/com.appname/cache/cache_file/journal.tmp
W/System.err: java.net.UnknownHostException: Kann Host lösen "www.domain.com": Keine Adresse mit Hostname
Ich habe diese tutorial gefolgt. Hier ist, wie ich ein Setup Retrofit (2.1.0):
import lu.CompanyName.R;
import lu.CompanyName.interfaces.CompanyNameAPI;
import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import static okhttp3.logging.HttpLoggingInterceptor.Level.HEADERS;
public class Injector {
private static final String CACHE_CONTROL = "Cache-Control";
private static Retrofit provideRetrofit (String baseUrl) {
return new Retrofit.Builder()
.baseUrl(baseUrl)
.client(provideOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
private static OkHttpClient provideOkHttpClient() {
return new OkHttpClient.Builder()
.addInterceptor(provideHttpLoggingInterceptor())
.addInterceptor(provideOfflineCacheInterceptor())
.addNetworkInterceptor(provideCacheInterceptor())
.cache(provideCache())
.build();
}
private static Cache provideCache() {
/*
Cache cache = null;
try
{
File dir = CompanyName.getInstance().getExternalCacheDir();
if (dir == null)
dir = CompanyName.getInstance().getCacheDir();
if (dir == null)
Log.e("provideCache", "dir is null");
cache = new Cache(new File(dir, "http-cache"), 10 * 1024 * 1024); // 10 MB
if (cache == null)
Log.e("provideCache", "cache is null");
}
catch (Exception e)
{
Log.e("provideCache", "Could not create Cache!");
}
return cache;*/
/*
File httpCacheDirectory = new File(CompanyName.getInstance().getCacheDir(), "responses");
httpCacheDirectory.getParentFile().mkdirs();
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(httpCacheDirectory, cacheSize);
try {
cache.initialize();
Iterator<String> iterator = cache.urls();
Log.i("provideCache", "URLs in cacheHttpClient : ");
while (iterator.hasNext()) {
Log.i("provideCache", iterator.next());
}
} catch (IOException e) {
e.printStackTrace();
Log.i("provideCache", "CACHE NOT INIT");
}
return cache;*/
return new Cache(new File(CompanyName.getInstance().getCacheDir(), "cache_file"), 20 * 1024 * 1024);
}
private static HttpLoggingInterceptor provideHttpLoggingInterceptor() {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HEADERS);
return httpLoggingInterceptor;
}
private 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.HOURS)
.build();
return response.newBuilder()
.header(CACHE_CONTROL, cacheControl.toString())
.build();
}
};*/
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
String cacheHeaderValue = CompanyName.getInstance().checkIfHasNetwork()
? "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();
}
};
}
private static Interceptor provideOfflineCacheInterceptor() {
/*return new Interceptor()
{
@Override
public Response intercept (Chain chain) throws IOException
{
Request request = chain.request();
if (!CompanyName.hasNetwork())
{
CacheControl cacheControl = new CacheControl.Builder()
//.maxStale(7, TimeUnit.DAYS)
.build();
request = request.newBuilder()
.cacheControl(cacheControl)
.build();
}
return chain.proceed(request);
}
};*/
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
String cacheHeaderValue = CompanyName.getInstance().checkIfHasNetwork()
? "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();
}
};
}
public static CompanyNameAPI provideCompanyNameAPI() {
return provideRetrofit(CompanyName.getInstance().getString(R.string.base_url)).create(CompanyNameAPI.class);
}
}
ich einige Lösungen versucht, über das Internet und Stackoverflow gefunden (noch im Kommentar im Code oben), weil ich zuerst dachte, es war ein „Cache-Control“ Problem neu schreiben.
Ich habe auch die Berechtigung READ_EXTERNAL_STORAGE und WRITE_EXTERNAL_STORAGE zum Manifest hinzugefügt, aber es ändert nichts.
Habe ich etwas übersehen? (Ich teste auf einem Samsung mit Android 6.0.1 API 23)
Nein Ich habe diese Erlaubnis bereits hinzugefügt. In der Tat, ich habe den oben beschriebenen Fehler nur, wenn ich Internet-Verbindung (Flugzeug-Modus) ausschalten: Mein Test besteht darin, die Daten ein erstes Mal (Internet on), um Cache zu bekommen, und dann um Daten aus dem Cache (Internet aus). – Bogy