Advertisement
Guest User

Untitled

a guest
Apr 21st, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.88 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement