2017-06-18 10 views
0

すべてを呼び出すのではなく、特定の呼び出しをキャッシュしたいのですが。これは私が今持っているが、それはすべての改造のコールに影響するコードです:Retrofit2 - 特定のAPI呼び出しのみをキャッシュする方法

int cacheSize = 10 * 1024 * 1024; // 10 MB 
Cache cache = new Cache(getCacheDir(), cacheSize); 

OkHttpClient okHttpClient = new OkHttpClient.Builder() 
    .cache(cache) 
    .build(); 

Retrofit.Builder builder = new Retrofit.Builder() 
    .baseUrl("http://10.0.2.2:3000/") 
    .client(okHttpClient) 
    .addConverterFactory(GsonConverterFactory.create()); 

Retrofit retrofit = builder.build(); 

は、私はちょうどそのコールのためのキャッシングをしたいとき、私は多分ヘッダに置くことができるものはありますか?例えば

//私はヘッダに何かを置くには十分だろう考えていました。私は、クライアント(アンドロイド)の呼び出しをキャッシュしたいだけです。だから私はretrofitが応答を覚えて、次の呼び出しのためにそれをキャッシュすることができると思っていたが、私はすべての私の呼び出し、ちょうど私が欲しいもの、おそらく1または2.それ以外はサーバーに常時接続することができます。これはどのように達成されましたか?

@Headers("Cache-Control:????XXXXX) //is it possible this way ?, how ? 
@GET("getBusiness.action")// Store information 
Call<RestaurantInfoModel> getRestaurantInfo(@Query("userId") String userId,@Query("businessId") String businessId); 

UPDATE:HERE

が、私は今試してみましたWHAT IS:ここ

は私がokhttpclientを構築する方法である:

final OkHttpClient.Builder builder = new OkHttpClient.Builder(); 
int cacheSize = 10 * 1024 * 1024; // 10 MB 
Cache cache = new Cache(getCacheDir(), cacheSize); 
if (BuildConfig.RETROFIT_LOG_ALL) { 
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); 
    logging.setLevel(HttpLoggingInterceptor.Level.BODY); 
    builder.addInterceptor(logging); 
} 
builder.cache(cache); 
return builder.build(); 

後、私は改造することを追加でそれは動作しますが、キャッシュでは見えません。

Content-Type: application/json; charset=utf-8 
06-18 17:54:58.044 11233-11735/com.mobile.myapp.staging D/OkHttp: Connection: close 
06-18 17:54:58.044 11233-11735/com.mobile.myapp.staging D/OkHttp: Transfer-Encoding: chunked 
06-18 17:54:58.044 11233-11735/com.mobile.myapp.staging D/OkHttp: X-Powered-By: Express 
06-18 17:54:58.044 11233-11735/com.mobile.myapp.staging D/OkHttp: Vary: Origin 
06-18 17:54:58.044 11233-11735/com.mobile.myapp.staging D/OkHttp: Access-Control-Allow-Credentials: true 
06-18 17:54:58.044 11233-11735/com.mobile.myapp.staging D/OkHttp: Cache-Control: public, max-age=0 
06-18 17:54:58.044 11233-11735/com.mobile.myapp.staging D/OkHttp: ETag: W/"39ba-G9evSsiVDp9GAVGu1Mk4ag" 
06-18 17:54:58.044 11233-11735/com.mobile.myapp.staging D/OkHttp: Date: Sun, 18 Jun 2017 10:54:58 GMT 

だからここに私は、キャッシングが動作しているかどうかを確認するために行ったテストは次のとおりです。okhttpするキャッシュを追加することなく、ヘッダの応答を見ることができます。 Androidデバイス上でSHUTDOWN Iその後、その後

public interface CountriesApi { 
    @GET("countries") 
    @Headers({"Content-Type:application/json"}) 
    Observable<List<CountryModel>> getCountries(); 
} 

インターネットを、まだコースのアプリでながら再びTEH同じコールを実行しようとしました:私はこれを使ってAPIにリクエストを行いました。しかし、代わりに、ネットワーク接続がないという不満を改装しました。代わりにキャッシュからちょうど得たはずです。どんなアイデアが間違っていますか?

java.net.SocketException: Network is unreachable at 
java.net.PlainSocketImpl.socketConnect(Native Method) at 
java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:334) at 
java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:196) 
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178) at 
java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356) at 
java.net.Socket.connect(Socket.java:586) at 
okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:63) 
at 
okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:223) 
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:149) 
at 
okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:192) 
at 
okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121) 
at 
okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100) 
at 
okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
at 
okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
at 
okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:211) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
at 
com.mobile.retrofit.NetworkSessionManager.intercept(NetworkSessionManager.java:38) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185) at 
okhttp3.RealCall.execute(RealCall.java:69) at 
retrofit2.OkHttpCall.execute(OkHttpCall.java:180) at 
retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41) 
at io.reactivex.Observable.subscribe(Observable.java:10842) at 
retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34) 
at io.reactivex.Observable.subscribe(Observable.java:10842) at 
io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) 
at io.reactivex.Observable.subscribe(Observable.java:10842) at 
io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96) 
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:452) at 
io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61) 
at 
io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) at 
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272) 
at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
at java.lang.Thread.run(Thread.java:761) 
+0

まず、https://stackoverflow.com/a/23503804/3225458をチェックし、前述のようにインターセプタを実装する必要があります。 – rom4ek

答えて

1

それはcaching (doc)を行いOkHttpライブラリだし、レスポンスヘッダによって主に駆動されます。それらを確認し、APIレスポンスがまったくキャッシュされているかどうかを確認する必要があります。 OkHttp logging interceptorはデバッグに役立ちます。

ネットワーク要求は、ネットワーク・インターセプターではなく、アプリケーションインターセプタとしてHttpLoggingInterceptorを使用して起こっているかどうかをチェックする(https://github.com/square/okhttp/wiki/Interceptorsを参照してください):要求がキャッシュによって処理されるときに

HttpLoggingInterceptor interceptor = HttpLoggingInterceptor(); 
interceptor.setLevel(Level.BASIC); 
OkHttpClient client = new OkHttpClient.Builder() 
.addNetworkInterceptor(new LoggingInterceptor()) 
.build(); 

ネットワークインターセプタは呼び出されません。

次の手順は状況によって異なります。

1)すべてのAPIリクエストがキャッシュされます。

その後、あなたは注釈@Headers( "のCache-Control:キャッシュなし")を使用することができるはずあなたはがキャッシュにしたくない方法のために。

2)すべてのAPIリクエストはキャッシュされません。

APIを変更して(適切なキャッシュヘッダーを追加する)、応答(ヘッダー)を変更するOkHttpに対してネットワークインターセプターを実装できます。このレスポンスでは、いくつかのインスピレーションを得ることができます:Can Retrofit with OKHttp use cache data when offline

+0

どうすればログからキャッシュのコピーを知ることができますか?私はインターネットを切断すれば簡単にはわかりますが、再構築するとネットワーク接続がなく、何も表示されない、または何も得られないという例外がスローされます。私も最大の年齢が0だったことに気づいた、それは重要です。私はokhttpclientに、自分の投稿ごとにビルダーで取るキャッシュオブジェクトを使用してキャッシュを設定させていました。 – j2emanue

+0

ロギングインターセプタをネットワークインターセプタ(ObのBuilderオブジェクトのaddNetworkInterceptor)として追加できます。ネットワークインターセプタはネットワークにアクセスするときにのみ呼び出されるため、キャッシュされたレスポンスはログに表示されません。これを含めるように回答を拡大します。 –

+0

そして、APIによって送信されるCache-Control:max-age = 0ヘッダーが重要であり、毎回Okhttpにネットワーク要求を強制します。 –

関連する問題