Saya mencoba menggunakan Retrofit & OKHttp untuk menyimpan tanggapan HTTP. Saya mengikuti intisari ini dan, berakhir dengan kode ini:
File httpCacheDirectory = new File(context.getCacheDir(), "responses");
HttpResponseCache httpResponseCache = null;
try {
httpResponseCache = new HttpResponseCache(httpCacheDirectory, 10 * 1024 * 1024);
} catch (IOException e) {
Log.e("Retrofit", "Could not create http cache", e);
}
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setResponseCache(httpResponseCache);
api = new RestAdapter.Builder()
.setEndpoint(API_URL)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(new OkClient(okHttpClient))
.build()
.create(MyApi.class);
Dan ini adalah MyApi dengan header Cache-Control
public interface MyApi {
@Headers("Cache-Control: public, max-age=640000, s-maxage=640000 , max-stale=2419200")
@GET("/api/v1/person/1/")
void requestPerson(
Callback<Person> callback
);
Pertama saya minta online dan periksa file cache. Respons dan header JSON yang benar ada di sana. Tetapi ketika saya mencoba untuk meminta offline, saya selalu mendapatkannya RetrofitError UnknownHostException
. Apakah ada hal lain yang harus saya lakukan untuk membuat Retrofit membaca respons dari cache?
EDIT:
Karena OKHttp 2.0.x HttpResponseCache
adalah Cache
, setResponseCache
adalahsetCache
Cache-Control: s-maxage=1209600, max-age=1209600
saya tidak tahu apakah itu cukup.public
kata kunci diperlukan dalam tajuk respons untuk membuatnya berfungsi offline. Tapi, tajuk ini tidak membiarkan OkClient menggunakan jaringan saat ada. Apakah ada cara untuk mengatur kebijakan / strategi cache untuk menggunakan jaringan bila tersedia?max-stale + max-age
disahkan, itu memang meminta dari jaringan. Tapi saya ingin mengatur max-basi seminggu. Ini membuatnya membaca respons dari cache bahkan jika ada jaringan yang tersedia.Jawaban:
Edit untuk Retrofit 2.x:
OkHttp Interceptor adalah cara yang tepat untuk mengakses cache saat offline:
1) Buat Interceptor:
2) Setup klien:
3) Tambahkan klien ke retrofit
Juga memeriksa @kosiara - Bartosz Kosarzycki 's jawaban . Anda mungkin perlu menghapus beberapa tajuk dari respons.
OKHttp 2.0.x (Periksa jawaban asli):
Karena OKHttp 2.0.x
HttpResponseCache
adalahCache
,setResponseCache
adalahsetCache
. Jadi, Anda harussetCache
seperti ini:Jawaban asli:
Ternyata respons server harus
Cache-Control: public
membuatOkClient
membaca dari cache.Jika Anda ingin meminta dari jaringan saat tersedia, Anda harus menambahkan
Cache-Control: max-age=0
header permintaan. Jawaban ini menunjukkan bagaimana melakukannya dengan parameter. Ini adalah bagaimana saya menggunakannya:sumber
HttpResponseCache has been renamed to Cache.** Install it with OkHttpClient.setCache(...) instead of OkHttpClient.setResponseCache(...)
.if (Utils.isNetworkAvailable(context))
benar atau itu seharusnya dibalik yaituif (!Utils.isNetworkAvailable(context))
?public okhttp3.Response intercept(Chain chain) throws IOException
tidak pernah dipanggil, itu hanya dipanggil ketika saya sedang onlineSemua jawaban di atas tidak bekerja untuk saya. Saya mencoba menerapkan cache offline di retrofit 2.0.0-beta2 . Saya menambahkan interceptor menggunakan
okHttpClient.networkInterceptors()
metode tetapi diterimajava.net.UnknownHostException
ketika saya mencoba menggunakan cache offline. Ternyata saya harus menambahkanokHttpClient.interceptors()
juga.Masalahnya adalah bahwa cache tidak ditulis ke penyimpanan flash karena server kembali
Pragma:no-cache
yang mencegah OkHttp menyimpan respons. Cache offline tidak berfungsi bahkan setelah memodifikasi nilai header permintaan. Setelah beberapa percobaan-dan-kesalahan saya membuat cache berfungsi tanpa memodifikasi sisi backend dengan menghapus pragma dari tanggapan alih-alih permintaan -response.newBuilder().removeHeader("Pragma");
Retrofit: 2.0.0-beta2 ; OkHttp: 2.5.0
...
...
sumber
interceptors ()
dannetworkInterceptors ()
identik. Mengapa Anda menduplikasi ini?.networkInterceptors().add()
daninterceptors().add()
?Solusi saya:
sumber
Jawabannya adalah YA, berdasarkan jawaban di atas, saya mulai menulis tes unit untuk memverifikasi semua kemungkinan penggunaan:
Saya membangun lib pembantu kecil untuk mengkonfigurasi cache OKHttp dengan mudah, Anda dapat melihat unittest terkait di sini di Github: https://github.com/ncornette/OkCacheControl/blob/master/okcache-control/src/test/java/com/ ncornette / cache / OkCacheControlTest.java
Terkecil yang menunjukkan penggunaan cache saat offline:
Seperti yang Anda lihat, cache dapat digunakan bahkan jika telah kedaluwarsa. Semoga ini bisa membantu.
sumber
membangun @ kosiara-Bartosz-kasarzycki ini jawaban , saya membuat sebuah proyek sampel yang benar beban dari memori-> Disk> jaringan menggunakan retrofit, okhttp, rxjava dan jambu biji. https://github.com/digitalbuddha/StoreDemo
sumber
Tembolok dengan Retrofit2 dan OkHTTP3:
Metode statis NetworkUtils.isNetworkAvailable ():
Kemudian tambahkan saja klien ke pembuat retrofit:
Sumber asli: https://newfivefour.com/android-retrofit2-okhttp3-cache-network-request-offline.html
sumber