All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.stanfy.enroscar.async.internal.WrapAsyncLoader Maven / Gradle / Ivy

Go to download

Helper classes and extended abstractions for Android loaders, content resolvers, and DB access.

There is a newer version: 2.1
Show newest version
package com.stanfy.enroscar.async.internal;

import android.os.Handler;
import android.os.Looper;
import android.support.v4.content.Loader;

import com.stanfy.enroscar.async.Async;
import com.stanfy.enroscar.async.AsyncObserver;

/**
 * Loader that backs {@link com.stanfy.enroscar.async.Async} result.
 * @param  data type
 *
 * @author Roman Mazur - Stanfy (http://stanfy.com)
 */
final class WrapAsyncLoader extends Loader> {

  /** Main thread handler. */
  private static final Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());

  private final AsyncContext context;
  private Async async;
  private Result result;

  /** Data observer. */
  private final AsyncObserver observer = new AsyncObserver() {
    @Override
    public void onError(final Throwable e) {
      post(new Result(null, e));
    }
    @Override
    public void onResult(final D data) {
      post(new Result<>(data, null));
    }
  };

  public WrapAsyncLoader(final AsyncContext context) {
    super(context.applicationContext);
    this.context = context;
  }

  @Override
  protected void onForceLoad() {
    if (async != null) {
      async.cancel();
    }
    async = context.provideAsync();
    if (async == null) {
      throw new IllegalArgumentException("Async can't be null. Have you implemented @Load or @Send method?");
    }

    async.subscribe(observer);
  }

  @Override
  protected void onStartLoading() {
    if (result != null) {
      deliverResult(result);
    }
    if (takeContentChanged() || async == null) {
      forceLoad();
    }
  }

  @Override
  public void deliverResult(final Result data) {
    if (isReset()) {
      onReleaseData(data);
      return;
    }

    Result oldData = result;
    result = data;

    if (isStarted()) {
      super.deliverResult(data);
    }

    if (oldData != null && data != oldData) {
      onReleaseData(oldData);
    }
  }

  @Override
  protected void onStopLoading() {
    if (async != null) {
      async.cancel();
      async = null;
    }
  }

  @Override
  protected void onReset() {
    if (result != null) {
      onReleaseData(result);
    }
  }

  private void onReleaseData(final Result result) {
    if (result.data != null) {
      context.releaseData(result.data);
    }
  }

  private void post(final Result result) {
    if (Looper.getMainLooper() == Looper.myLooper()) {
      deliverResult(result);
    } else {
      MAIN_HANDLER.post(new Runnable() {
        @Override
        public void run() {
          deliverResult(result);
        }
      });
    }
  }

  /** Execution result. */
  static final class Result {
    final D data;
    final Throwable error;

    Result(final D data, final Throwable error) {
      this.data = data;
      this.error = error;
    }

    @Override
    public boolean equals(final Object o) {
      if (!(o instanceof Result)) {
        return false;
      }
      @SuppressWarnings("unchecked")
      Result r = (Result) o;
      if (data == null && error == null) {
        return r.data == null && r.error == null;
      }
      return data != null ? data.equals(r.data) : error.equals(r.error);
    }

    @Override
    public int hashCode() {
      if (data == null && error == null) {
        return 0;
      }
      return data != null ? data.hashCode() : error.hashCode();
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy