2017-01-17 10 views
1

Привет, я пытаюсь кэшировать запрос 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

ответ

1

есть заголовок «должен перепроверить», так что вы не можете прочитать непосредственно из кэша

Если вы попытаетесь удалить его, например, с помощью чарльз-прокси, он должен работать, как вы ожидаете. Поскольку я не знаю, чего вы пытаетесь достичь, я не могу сказать вам, какое лучшее решение для вас было бы.

+0

Я хочу получить данные в автономном режиме, если я уже их кешировал. В первый раз, когда я запустил приложение, он будет подключен к сети, если пользователь потеряет соединение, я хочу использовать кеш. – AmirG

+1

прочитайте «must-revalidate» как заголовок HTTP-кеша. Reddit не хочет, чтобы вы использовали эти данные, не отправляя запрос главы, чтобы проверить, остается ли информация одинаковой. Если ничего не изменится, вы получите ответ 304 без тела, и вам будет разрешено использовать кеш. обычно вам нужно просто сохранить нужную информацию прямо в приложении. может быть возможно перехватить запрос и удалить этот заголовок вручную, но это не так, как должно быть сделано. – user1625744

+0

Спасибо! я думаю, я поеду на сохранение на sharepreferences или что-то подобное в первый раз, когда я смогу разобрать json. Имейте приятный день :) – AmirG

 Смежные вопросы

  • Нет связанных вопросов^_^