项目作者: ddiffa

项目描述 :
An example of how to use Retrofit2 to cache HTTP responses
高级语言: Java
项目地址: git://github.com/ddiffa/Caching-Example.git
创建时间: 2019-06-23T19:16:08Z
项目社区:https://github.com/ddiffa/Caching-Example

开源协议:

下载


Caching is a way of temporarily storing data fetched from a network on a device’s storage, so that we can access it at a later time when the device is offline or if we want to access the same data again.
In the following section, I’ll do a Retrofit Request with OkHttp as the Client and using RxJava.
We’ll cache the requests such that they can be displayed the next time if there is no internet/problem in getting the latest request.

I use several libraries in this project :

Library

  • RxJava
  • Retrofit
  • OkHttp
  • Glide
  • Lombok
  • ButterKnife

Benefits of Caching

  • Reduces bandwidth consumption
  • Saves you time you’d spend waiting for the server to give you the network response.
  • Saves the server the burden of additional traffic.
  • if you need to access the same network resource again after having accessed it recently, your device won’t need to make a request to the server, it’ll get the cached response instead.

Creating a cache

Step 1 : Define a Class to Check for internet connectivity

We first need to have a class in our app that checks for internet connectivity.

  1. public class MyApplication extends Application {
  2. private static MyApplication instance;
  3. @Override
  4. public void onCreate() {
  5. super.onCreate();
  6. if(instance == null){
  7. instance = this;
  8. }
  9. }
  10. public static MyApplication getInstance(){
  11. return instance;
  12. }
  13. public static boolean hasNetwork(){
  14. return instance.isNetworkConnected();
  15. }
  16. private boolean isNetworkConnected(){
  17. ConnectivityManager cm =
  18. (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
  19. NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
  20. return activeNetwork != null &&
  21. activeNetwork.isConnectedOrConnecting();
  22. }
  23. }

Step 2 : Defining the size of the cahce

The following line of code specifies a cache of 5MB.

  1. private static final long = 5 * 1024 * 1024;

Step 3 : Creating Method Cache and Interceptor

  1. private static Cache cache(){
  2. return new Cache(new File(MyApplication.getInstance().getCacheDir(),"someIdentifier"), cacheSize);
  3. }

And we need to add an Interceptor, which is responsible for observing and modifying request going out and the corresponding responses coming back in.

This interceptor will be called both if the network is available and if the network is not available.
Setting the max age to 7 Days, which means the cache will be valid for 7 Days.
For example, the first request will be getting response from the server, and the following request made within 7 Days of the first request will be getting response from the cache.

  1. private static Interceptor offlineInterceptor() {
  2. return new Interceptor() {
  3. @Override
  4. public Response intercept(Chain chain) throws IOException {
  5. Log.d(TAG, "offline interceptor: called.");
  6. Request mRequest = chain.request();
  7. // prevent caching when network is on. For that we use the "networkInterceptor"
  8. if (!MyApplication.hasNetwork()) {
  9. CacheControl mCacheControl = new CacheControl.Builder()
  10. .maxStale(7, TimeUnit.DAYS)
  11. .build();
  12. mRequest = request.newBuilder()
  13. .removeHeader(HEADER_PRAGMA)
  14. .removeHeader(HEADER_CACHE_CONTROL)
  15. .cacheControl(mCacheControl)
  16. .build();
  17. }
  18. return chain.proceed(mRequest);
  19. }
  20. };
  21. }

This interceptor will be called ONLY if the network is available

  1. private static Interceptor networkInterceptor() {
  2. return new Interceptor() {
  3. @Override
  4. public Response intercept(Chain chain) throws IOException {
  5. Log.d(TAG, "network interceptor: called.");
  6. Response mResponse = chain.proceed(chain.request());
  7. CacheControl mCacheControl = new CacheControl.Builder()
  8. .maxAge(5, TimeUnit.SECONDS)
  9. .build();
  10. return mResponse.newBuilder()
  11. .removeHeader(HEADER_PRAGMA)
  12. .removeHeader(HEADER_CACHE_CONTROL)
  13. .header(HEADER_CACHE_CONTROL, mCacheControl.toString())
  14. .build();
  15. }
  16. };
  17. }

Step 4 : Creating the OkHttpClient with an interceptor

The following gist explains how to add this to our OkHttpClient, along with adding our cache :

  1. OkHttpClient okHttpClient = new OkHttpClient.Builder()
  2. .cache(cache())
  3. .connectTimeout(60, TimeUnit.SECONDS)
  4. .readTimeout(60, TimeUnit.SECONDS)
  5. .addInterceptor(makeLoggingInterceptor(true))
  6. .addNetworkInterceptor(networkInterceptor())
  7. .addInterceptor(offlineInterceptor())
  8. .build();

Now we need to add this OkHttpClient to our Retrofit instance. Here’s how to do that :

  1. api = new Retrofit.Builder()
  2. .baseUrl(BASE_URL)
  3. .client(okHttpClient)
  4. .addConverterFactory(GsonConverterFactory.create())
  5. .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  6. .build()
  7. .create(Api.class);

Cappy Hodding