Привет, я пытаюсь кэшировать запрос GET, который я делаю из службы reddit. Я тестировал с другим api и работал, но я не могу найти причину, по которой я не могу контролировать кеш на этом. Я вижу, как данные кеша поднимаются в настройках приложения, когда я могу использовать json в Интернете. Но когда я отключить подключение к Интернету (самолетный режим) я получаю эту ошибку:HTTP FAILED: java.net.UnknownHostException: Не удается разрешить хост «www.reddit.com»: нет адреса, связанного с именем хоста
01-17 06:00:05.524 17363-17429/com.amirgb.reddittestapp.debug D/OkHttp: --> GET https://www.reddit.com/reddits.json http/1.1 01-17 06:00:05.524 17363-17429/com.amirgb.reddittestapp.debug D/OkHttp: --> END GET 01-17 06:00:05.531 17363-17429/com.amirgb.reddittestapp.debug D/OkHttp: <-- HTTP FAILED: java.net.UnknownHostException: Unable to resolve host "www.reddit.com": No address associated with hostname
Im испытание на Moto г 4 плюса апите 23 я пытался с https://itunes.apple.com/us/rss/topfreeapplications/limit=20/json службы и кэш делает работу, так что, может быть, есть разница в reddit заголовок? ,
Мой класс restclient:
import android.content.Context;
import android.widget.ImageView;
import com.amirgb.reddittestapp.BuildConfig;
import com.amirgb.reddittestapp.R;
import com.amirgb.reddittestapp.RedditTestApplication;
import com.amirgb.reddittestapp.model.RedditResponse;
import com.amirgb.reddittestapp.util.NetWorkUtils;
import java.io.File;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public final class RedditApiService {
private static IRedditApi mRedditApi;
private static OkHttpClient mClient;
/**
* Inits retrofit
*/
static {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
File httpCacheDirectory = new File(RedditTestApplication.getInstance().getCacheDir(), "reddit");
Cache cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024);
mClient = new OkHttpClient.Builder()
.cache(cache)
.addInterceptor(chain -> {
Request request = chain.request();
if (NetWorkUtils.isNetworkAvailable(RedditTestApplication.getInstance())) {
request = request.newBuilder()
.cacheControl(new CacheControl.Builder()
.maxAge(0, TimeUnit.SECONDS)
.maxStale(365, TimeUnit.DAYS).build())
.build();
}
Response originalResponse = chain.proceed(request);
if (NetWorkUtils.isNetworkAvailable(RedditTestApplication.getInstance())) {
int maxAge = 60 * 60;
return originalResponse.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
int maxStale = 60 * 60 * 24 * 28;
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
})
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.addInterceptor(interceptor)
.build();
Retrofit mRetrofit = new Retrofit.Builder()
.baseUrl(IRedditApi.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(mClient)
.build();
mRedditApi = mRetrofit.create(IRedditApi.class);
}
/**
* Get subjects from service api
*
* @param callback
*/
public static void getSubjects(Callback<RedditResponse> callback) {
Call<RedditResponse> call = mRedditApi.getSubjects();
call.enqueue(callback);
}
Мой метод сети Util:
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
Мой Модифицированная интерфейс:
public interface IRedditApi {
String BASE_URL = "https://www.reddit.com";
@GET("/reddits.json")
Call<RedditResponse> getSubjects();}
Reddit réponse Заголовок:
accept-ranges →bytes access-control-allow-origin →* access-control-expose-headers →X-Reddit-Tracking, X-Moose cache-control →max-age=0, must-revalidate content-encoding →gzip content-length →79113 content-type →application/json; charset=UTF-8 date →Tue, 17 Jan 2017 09:16:52 GMT status →200 strict-transport-security →max-age=15552000; includeSubDomains; preload vary →accept-encoding via →1.1 varnish x-cache →MISS x-cache-hits →0 x-content-type-options →nosniff x-frame-options →SAMEORIGIN x-moose →majestic x-reddit-tracking → https://pixel.redditmedia.com/pixel/of_destiny.png?v=W9eORuZE%2BzXXBRZc%2BikbQ8aTR0a7BSLeoE9DDYvuCihjMAifTK%2Bdsr%2F0gX8rDES98kR5xK2vVWc%3D x-served-by →cache-dfw1841-DFW x-timer →S1484644612.225905,VS0,VE254 x-ua-compatible →IE=edge x-xss-protection →1; mode=block
Я хочу получить данные в автономном режиме, если я уже их кешировал. В первый раз, когда я запустил приложение, он будет подключен к сети, если пользователь потеряет соединение, я хочу использовать кеш. – AmirG
прочитайте «must-revalidate» как заголовок HTTP-кеша. Reddit не хочет, чтобы вы использовали эти данные, не отправляя запрос главы, чтобы проверить, остается ли информация одинаковой. Если ничего не изменится, вы получите ответ 304 без тела, и вам будет разрешено использовать кеш. обычно вам нужно просто сохранить нужную информацию прямо в приложении. может быть возможно перехватить запрос и удалить этот заголовок вручную, но это не так, как должно быть сделано. – user1625744
Спасибо! я думаю, я поеду на сохранение на sharepreferences или что-то подобное в первый раз, когда я смогу разобрать json. Имейте приятный день :) – AmirG