Skip to content

Instantly share code, notes, and snippets.

@LouisCAD
Created April 3, 2016 15:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LouisCAD/bd1d1c1ed900e8f8f62c8192cbb96bc1 to your computer and use it in GitHub Desktop.
Save LouisCAD/bd1d1c1ed900e8f8f62c8192cbb96bc1 to your computer and use it in GitHub Desktop.
A base class to load from Google Play Services on Android. Inspired by this: https://medium.com/google-developers/making-loading-data-on-android-lifecycle-aware-897e12760832#.d7rqcayvb
import android.content.Context;
import android.content.Loader;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import timber.log.Timber;
public abstract class GoogleApiClientLoader<D> extends Loader<D>
implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
/**
* Do not call {@link GoogleApiClient#disconnect()} on this object, except from
* {@link GoogleApiClientLoader} class.
*/
@NonNull
public final GoogleApiClient mGoogleApiClient;
@Nullable
protected D mData;
@Nullable
private ConnectionResult mConnectionResult;
/**
* Stores away the application context associated with context.
* Since Loaders can be used across multiple activities it's dangerous to
* store the context directly; always use {@link #getContext()} to retrieve
* the Loader's Context, don't use the constructor argument directly.
* The Context returned by {@link #getContext} is safe to use across
* Activity instances.
*
* @param context used to retrieve the application context.
*/
public GoogleApiClientLoader(Context context) {
super(context);
mGoogleApiClient = getNewApiClient();
}
@Override
protected final void onStartLoading() {
if (mData != null) deliverResult(mData);
if (mGoogleApiClient.isConnected()) {
startLoadingData(mGoogleApiClient);
// FIXME: 01/04/16 request data from child class
} else mGoogleApiClient.connect();
}
protected abstract void startLoadingData(@NonNull GoogleApiClient googleApiClient);
protected final void onResult(D data) {
mData = data;
deliverResult(data);
}
@Override
protected final void onForceLoad() {
if (mData != null) deliverResult(mData);
if (!mGoogleApiClient.isConnected()) mGoogleApiClient.connect();
}
@Override
public final void onConnected(@Nullable Bundle connectionHint) {
mConnectionResult = null;
if (mData != null) deliverResult(mData);
startLoadingData(mGoogleApiClient);
}
@Override
public final void onConnectionSuspended(int cause) {
Timber.wtf("onConnectionSuspended(cause=%d)", cause);
deliverResult(null);
}
@Override
public final void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
mConnectionResult = connectionResult;
deliverResult(null);
}
protected abstract void onGoogleApiClientDisconnect();
@Override
protected final void onReset() {
if (mGoogleApiClient.isConnected()) {
onGoogleApiClientDisconnect();
mGoogleApiClient.disconnect();
}
}
/**
* @return the connection result if {@link #mGoogleApiClient} connection failed,
* or null otherwise.
*/
@Nullable
public final ConnectionResult getConnectionResult() {
return mConnectionResult;
}
@NonNull
protected abstract GoogleApiClient getNewApiClient();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment