Last active
August 29, 2015 14:15
-
-
Save czyrux/8d36a70bb1babbde8540 to your computer and use it in GitHub Desktop.
Utility Loader class implementation which extends AsyncTaskLoader and handles caveats regarding loader lifecycle. It also provides error handling and a helper class to decouple the loader job task.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.support.v4.content.AsyncTaskLoader; | |
/** | |
* Loader which extends AsyncTaskLoader and handles caveats as pointed out in | |
* http://code.google.com/p/android/issues/detail?id=14944. | |
* <p/> | |
* | |
* @param <T> data type | |
* @author Antonio Gutierrez <[email protected]> | |
*/ | |
public class AsyncLoader<T> extends AsyncTaskLoader<LoaderResult<T>> { | |
private LoaderResult<T> result; | |
private final LoaderTask<T> task; | |
private volatile boolean loading; | |
public AsyncLoader(Context ctx, LoaderTask<T> task) { | |
super(ctx); | |
if (task == null) { | |
throw new IllegalArgumentException("LoaderTask cannot be null"); | |
} | |
this.task = task; | |
} | |
@Override | |
protected void onStartLoading() { | |
if (result != null) { | |
// Deliver any previously loaded data immediately. | |
deliverResult(result); | |
} | |
// If there is not current data, start the job. | |
forceLoad(); | |
} | |
@Override | |
public LoaderResult<T> loadInBackground() { | |
loading = true; | |
LoaderResult<T> data; | |
try { | |
T content = task.getData(); | |
data = new LoaderResult<>(content); | |
} catch (Exception e) { | |
data = new LoaderResult<>(e); | |
} | |
return data; | |
} | |
@Override | |
protected void onStopLoading() { | |
// The Loader is in a stopped state, so we should attempt to cancel the | |
// current load (if there is one). | |
cancelLoad(); | |
} | |
@Override | |
public void deliverResult(LoaderResult<T> dataLoaded) { | |
loading = false; | |
if (isReset()) { | |
// The Loader has been reset; ignore the result and invalidate the data. | |
result = null; | |
return; | |
} | |
this.result = dataLoaded; | |
if (isStarted()) { | |
// If the Loader is in a started state, deliver the results to the | |
// client. The superclass method does this for us. | |
super.deliverResult(result); | |
} | |
} | |
@Override | |
protected void onReset() { | |
// Ensure the loader has been stopped. | |
onStopLoading(); | |
// Release resources. | |
result = null; | |
} | |
public boolean isLoading() { | |
return loading; | |
} | |
public boolean hasMoreData() { | |
return task.hasMoreData(); | |
} | |
public void load() { | |
// It will force load unless there is nothing already loading | |
if (!isLoading()) { | |
super.forceLoad(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Result obtained from an AsyncLoader task. | |
* @param <T> data type | |
* @author Antonio Gutierrez <[email protected]> | |
*/ | |
public class LoaderResult<T> { | |
private final T data; | |
private final Exception errorException; | |
public LoaderResult(T data) { | |
this.data = data; | |
this.errorException = null; | |
} | |
public LoaderResult(Exception errorException) { | |
this.errorException = errorException; | |
this.data = null; | |
} | |
public boolean isOk() { | |
return data != null; | |
} | |
public T getData() { | |
return data; | |
} | |
public Exception getErrorException() { | |
return errorException; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Carry out the task of loading the data for AsyncLoader. | |
* It can perform IO or network task. | |
* @param <T> data type | |
* @author Antonio Gutierrez <[email protected]> | |
*/ | |
public interface LoaderTask<T> { | |
public T getData(); | |
boolean hasMoreData(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment