Guest User

Untitled

a guest
Mar 20th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.83 KB | None | 0 0
  1. package be.digitalia.arch.lifecycle;
  2.  
  3. import android.arch.lifecycle.LiveData;
  4. import android.arch.lifecycle.MutableLiveData;
  5. import android.os.AsyncTask;
  6. import android.support.annotation.MainThread;
  7. import android.support.annotation.NonNull;
  8. import android.support.annotation.VisibleForTesting;
  9. import android.support.annotation.WorkerThread;
  10.  
  11. import java.util.concurrent.atomic.AtomicBoolean;
  12.  
  13. /**
  14. * A LiveData class that can be invalidated & computed on demand.
  15. *
  16. * @param <T> The type of the live data
  17. */
  18. public abstract class ComputableLiveData<T> {
  19.  
  20. private final MutableLiveData<T> mLiveData;
  21.  
  22. private final AtomicBoolean mInvalid = new AtomicBoolean(true);
  23. private final AtomicBoolean mComputing = new AtomicBoolean(false);
  24.  
  25. /**
  26. * Creates a computable live data which is computed when there are active observers.
  27. * <p>
  28. * It can also be invalidated via {@link #invalidate()} which will result in a call to
  29. * {@link #compute()} if there are active observers (or when they start observing)
  30. */
  31. public ComputableLiveData() {
  32. mLiveData = new MutableLiveData<T>() {
  33. @Override
  34. protected void onActive() {
  35. AsyncTask.THREAD_POOL_EXECUTOR.execute(mRefreshRunnable);
  36. }
  37. };
  38. }
  39.  
  40. /**
  41. * Returns the LiveData managed by this class.
  42. *
  43. * @return A LiveData that is controlled by ComputableLiveData.
  44. */
  45. @NonNull
  46. public LiveData<T> getLiveData() {
  47. return mLiveData;
  48. }
  49.  
  50. @VisibleForTesting
  51. final Runnable mRefreshRunnable = new Runnable() {
  52. @WorkerThread
  53. @Override
  54. public void run() {
  55. boolean computed;
  56. do {
  57. computed = false;
  58. if (mComputing.compareAndSet(false, true)) {
  59. try {
  60. T value = null;
  61. while (mInvalid.compareAndSet(true, false)) {
  62. computed = true;
  63. value = compute();
  64. }
  65. if (computed) {
  66. mLiveData.postValue(value);
  67. }
  68. } finally {
  69. mComputing.set(false);
  70. }
  71. }
  72. } while (computed && mInvalid.get());
  73. }
  74. };
  75.  
  76. /**
  77. * Invalidates the LiveData.
  78. * <p>
  79. * When there are active observers, this will trigger a call to {@link #compute()}.
  80. */
  81. @MainThread
  82. public void invalidate() {
  83. boolean isActive = mLiveData.hasActiveObservers();
  84. if (mInvalid.compareAndSet(false, true)) {
  85. if (isActive) {
  86. AsyncTask.THREAD_POOL_EXECUTOR.execute(mRefreshRunnable);
  87. }
  88. }
  89. }
  90.  
  91. @SuppressWarnings("WeakerAccess")
  92. @WorkerThread
  93. protected abstract T compute();
  94. }
Add Comment
Please, Sign In to add comment