Cache de resposta do OkHttp 3 (java.net.UnknownHostException)
Estou realmente preso a esse problema.
Quero armazenar em cache a resposta do servidor por algum tempo para usar os dados quando o dispositivo estiver offline. Então eu configurei um cache para o meuOkHttpClient
. Também eu definoCache-Contlol
cabeçalho.
Aqui está o meu código:
public class MainActivity extends AppCompatActivity {
Retrofit retrofit;
RecyclerView recyclerView;
RandomUserAdapter mAdapter;
Cache cache;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
cache = provideOkHttpCache();
Timber.plant(new Timber.DebugTree());
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
populateUsers();
}
});
Interceptor cacheInterceptor = new Interceptor() {
@Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
okhttp3.Response originalResponse = chain.proceed(chain.request());
okhttp3.Response modifyedResponse = originalResponse;
if (true) {
modifyedResponse = originalResponse.newBuilder()
.header("Cache-Control", "max-age=86400")
.build();
}
return modifyedResponse;
}
};
HttpLoggingInterceptor httpLoggingInterceptor = new
HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(@NonNull String message) {
Timber.i(message);
}
});
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient()
.newBuilder()
.addInterceptor(httpLoggingInterceptor)
.addInterceptor(cacheInterceptor)
.cache(cache)
.build();
retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://randomuser.me/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
populateUsers();
}
private void initViews() {
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
button = findViewById(R.id.button);
}
private void populateUsers() {
Call<RandomUsers> randomUsersCall = getRandomUserService().getRandomUsers(10);
randomUsersCall.enqueue(new Callback<RandomUsers>() {
@Override
public void onResponse(Call<RandomUsers> call, @NonNull Response<RandomUsers> response) {
if (response.isSuccessful()) {
Log.v("cache-control", "using cache = " + isFromCache(response));
mAdapter = new RandomUserAdapter();
mAdapter.setItems(response.body().getResults());
recyclerView.setAdapter(mAdapter);
}
}
@Override
public void onFailure(Call<RandomUsers> call, Throwable t) {
Timber.i(t.getMessage());
Log.v("cache-control", "response failure");
}
});
}
public RandomUsersApi getRandomUserService() {
return retrofit.create(RandomUsersApi.class);
}
Cache provideOkHttpCache() {
int cacheSize = 10 * 1024 * 1024; // 100 MiB
File cacheDir = new File("cachedirectory");
Cache cache = new Cache(cacheDir, cacheSize);
return cache;
}
public boolean isFromCache(Response response) {
return response.raw().cacheResponse() != null;
}
}
Parece que tudo vai ficar bem. Então eu faço isso:
executar aplicativoveja os logs do OkHttp e na tela para ter certeza de que recebemos dados com sucessofechar aplicativoativar o modo de voo no dispositivo (todas as redes desativadas)executar aplicativoNeste momento, espero que o aplicativo use dados em cache. Mas isso não acontece. Eu tenho apenas tela em branco eHTTP FAILED: java.net.UnknownHostException: Unable to resolve host "randomuser.me": No address associated with hostname
no meu logcat.