SHARE
TWEET

Untitled

a guest Apr 21st, 2019 69 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package com.nirmal.jeffrey.flickvibes.util;
  2.  
  3.  
  4. import android.arch.lifecycle.LiveData;
  5. import android.arch.lifecycle.MediatorLiveData;
  6. import android.arch.lifecycle.Observer;
  7. import android.support.annotation.MainThread;
  8. import android.support.annotation.NonNull;
  9. import android.support.annotation.Nullable;
  10. import android.support.annotation.WorkerThread;
  11. import android.util.Log;
  12. import com.nirmal.jeffrey.flickvibes.executor.AppExecutor;
  13. import com.nirmal.jeffrey.flickvibes.network.response.ApiResponse;
  14.  
  15. // CacheObject: Type for the Resource data.
  16. // RequestObject: Type for the API response.
  17. public abstract class NetworkBoundResource<CacheObject, RequestObject> {
  18.  
  19.   private static final String TAG = "NetworkBoundResource";
  20.   private MediatorLiveData<Resource<CacheObject>> results = new MediatorLiveData<>();
  21.   private AppExecutor appExecutor;
  22.  
  23.   public NetworkBoundResource(AppExecutor appExecutor) {
  24.     this.appExecutor = appExecutor;
  25.     init();
  26.   }
  27.  
  28.   /**
  29.    * 1) Update loading status and Observe Local database 2) if(condition) - stop observing the local
  30.    * database - insert new data into th database from network - start observing the database 3) else
  31.    * - Update success status with existing cacheObject
  32.    */
  33.   private void init() {
  34.     //Update LiveData for loading status
  35.     results.setValue((Resource<CacheObject>) Resource.loading(null));
  36.     //observe liveData from the database
  37.     final LiveData<CacheObject> dbSource = loadFromDb();
  38.     // add the dbSource to mediator liveData
  39.     results.addSource(dbSource, new Observer<CacheObject>() {
  40.       @Override
  41.       public void onChanged(CacheObject cacheObject) {
  42.         results.removeSource(dbSource);
  43.         if (shouldFetch(cacheObject)) {
  44.           //get data from the network
  45.           fetchFromNetwork(dbSource);
  46.         } else {
  47.           results.addSource(dbSource, new Observer<CacheObject>() {
  48.             @Override
  49.             public void onChanged(CacheObject cacheObject) {
  50.               setValue(Resource.success(cacheObject));
  51.             }
  52.           });
  53.         }
  54.       }
  55.     });
  56.  
  57.   }
  58.  
  59.   private void fetchFromNetwork(final LiveData<CacheObject> dbSource) {
  60.     Log.d(TAG, "fetchFromNetwork: Called.");
  61.     results.addSource(dbSource, new Observer<CacheObject>() {
  62.       @Override
  63.       public void onChanged(CacheObject cacheObject) {
  64.         setValue((Resource.loading(cacheObject)));
  65.  
  66.       }
  67.     });
  68.     final LiveData<ApiResponse<RequestObject>> apiResponse = createCall();
  69.     results.addSource(apiResponse, new Observer<ApiResponse<RequestObject>>() {
  70.       @Override
  71.       public void onChanged(final ApiResponse<RequestObject> requestObjectApiResponse) {
  72.         results.removeSource(dbSource);
  73.         results.removeSource(apiResponse);
  74.  
  75.         Log.d(TAG, "run: Attempting to refresh data from network");
  76.         /*
  77.          3 cases:
  78.          1) ApiSuccessResponse
  79.          2) ApiErrorResponse
  80.          3) ApiEmptyResponse
  81.          */
  82.         if (requestObjectApiResponse instanceof ApiResponse.ApiSuccessResponse) {
  83.           Log.d(TAG, "onChanged: onApiSucess");
  84.           appExecutor.diskIO().execute(new Runnable() {
  85.             @Override
  86.             public void run() {
  87.               //save the response to local database
  88.               saveCallResult((RequestObject)processResponse((ApiResponse.ApiSuccessResponse)requestObjectApiResponse));
  89.               appExecutor.mainThread().execute(new Runnable() {
  90.                 @Override
  91.                 public void run() {
  92.                   results.addSource(loadFromDb(), new Observer<CacheObject>() {
  93.                     @Override
  94.                     public void onChanged(CacheObject cacheObject) {
  95.                       setValue(Resource.success(cacheObject));
  96.                     }
  97.                   });
  98.                 }
  99.               });
  100.             }
  101.           });
  102.  
  103.  
  104.         } else if (requestObjectApiResponse instanceof ApiResponse.ApiEmptyResponse) {
  105.           Log.d(TAG, "onChanged: onApiEmpty");
  106.           appExecutor.mainThread().execute(new Runnable() {
  107.             @Override
  108.             public void run() {
  109.               results.addSource(loadFromDb(), new Observer<CacheObject>() {
  110.                 @Override
  111.                 public void onChanged(CacheObject cacheObject) {
  112.                   setValue(Resource.success(cacheObject));
  113.                 }
  114.               });
  115.             }
  116.           });
  117.  
  118.         } else if (requestObjectApiResponse instanceof ApiResponse.ApiErrorResponse) {
  119.           Log.d(TAG, "onChanged: onApiError");
  120.           results.addSource(dbSource, new Observer<CacheObject>() {
  121.             @Override
  122.             public void onChanged(CacheObject cacheObject) {
  123.               setValue(
  124.                   Resource.error(
  125.                       ((ApiResponse.ApiErrorResponse) requestObjectApiResponse).getErrorMessage(),
  126.                       cacheObject));
  127.             }
  128.           });
  129.         }
  130.       }
  131.     });
  132.  
  133.   }
  134.  
  135.   private CacheObject processResponse(ApiResponse.ApiSuccessResponse response) {
  136.     return (CacheObject) response.getBody();
  137.   }
  138.  
  139.   private void setValue(Resource<CacheObject> newValue) {
  140.     if (results.getValue() != newValue) {
  141.       results.setValue(newValue);
  142.     }
  143.   }
  144.  
  145.  
  146.   // Called to save the result of the API response into the database.
  147.   @WorkerThread
  148.   protected abstract void saveCallResult(@NonNull RequestObject item);
  149.  
  150.   // Called with the data in the database to decide whether to fetch
  151.   // potentially updated data from the network.
  152.   @MainThread
  153.   protected abstract boolean shouldFetch(@Nullable CacheObject data);
  154.  
  155.   // Called to get the cached data from the database.
  156.   @NonNull
  157.   @MainThread
  158.   protected abstract LiveData<CacheObject> loadFromDb();
  159.  
  160.   // Called to create the API call.
  161.   @NonNull
  162.   @MainThread
  163.   protected abstract LiveData<ApiResponse<RequestObject>> createCall();
  164.  
  165.  
  166.   // Returns a LiveData object that represents the resource that's implemented
  167.   // in the base class.
  168.   public final LiveData<Resource<CacheObject>> getAsLiveData() {
  169.     return results;
  170.   }
  171.  
  172.   ;
  173. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top