package com.getbase.android.db.loaders;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
/**
* Base class for {@link android.support.v4.content.Loader} which caches
* the results.
*/
public abstract class AbstractLoader<T> extends AsyncTaskLoader<T> {
T mResult;
public AbstractLoader(Context context) {
super(context);
}
@Override
public void deliverResult(T result) {
if (isReset()) {
releaseResources(result);
return;
}
T oldResult = mResult;
mResult = result;
if (isStarted()) {
if (oldResult != result) {
try {
onNewDataDelivered(result);
} catch (Throwable t) {
throw new RuntimeException("Error occurred on delivering new data in loader: " + this, t);
}
}
super.deliverResult(result);
}
if (oldResult != result && oldResult != null) {
releaseResources(oldResult);
}
}
@Override
public void onCanceled(T result) {
super.onCanceled(result);
releaseResources(result);
}
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
releaseResources(mResult);
mResult = null;
}
@Override
protected void onStartLoading() {
if (mResult != null) {
deliverResult(mResult);
}
if (takeContentChanged() || mResult == null) {
forceLoad();
}
}
@Override
protected void onStopLoading() {
cancelLoad();
}
/**
* Subclasses may implement this to take care of releasing resources held
* by {@code result}.
* This will always be called from the process's main thread.
*/
protected void releaseResources(T result) {
}
/**
* Subclasses may implement this to perform some action when new data is
* delivered for the first time. For example you might want to register
* some observers which would trigger reloading of the data. You do not
* want to do this in onStartLoading, because the user would never get any
* data if the loading time was longer than interval between forceLoad
* triggers from observer.
*
* This will always be called from the process's main thread.
*/
protected void onNewDataDelivered(T data) {
}
}