Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Better Implementation of AsyncTask in Android

Better Implementation of AsyncTask in Android

This is a custom wrapper of Android AsyncTask that I use in my projects. It has more convenient fluent API for managing async operations and supports flexible exception handling. You can omit methods that you do not need, like onBefore(...) or onAfter(...). Also you do not need to inherit AsyncTask for each background task.

Example of usage

Background operation with result

Task.create(() -> getResultsInBackground())
    .onBefore(() -> doBeforeTaskOnMainThread())
    .onAfter(() -> doAfterTaskOnMainThread())
    .onSuccess(result -> {
        // Do something with result.
    })
    .onError(ex -> {
        // Log the exception.
    })  
    .execute(getContext());

Background operation without result

Task.create(() -> doSomethingInBackground())
    .onBefore(() -> doBeforeTaskOnMainThread())
    .onAfter(() -> doAfterTaskOnMainThread())
    .onSuccess(() -> {
        // Operation succeded. Do something.
    })
    .onError(ex -> {
        // Log the exception.
    })  
    .execute(this);
public class ParameterlessTask extends Task {
private static final String TAG = ParameterlessTask.class.getSimpleName();
protected Callable0 mCallable = null;
protected Action0 mOnBefore = null;
protected Action0 mOnSuccess = null;
protected Action<Throwable> mOnError = null;
protected Action0 mOnAfter = null;
protected long mDelay = 0;
protected Throwable mException = null;
/**
* Executes task and passes result within specified context.
* @param context
*/
public void execute(Context context) {
AsyncTaskCompat.executeParallel(
new AsyncTask<Void, Void, Void>() {
private Throwable mException = null;
@Override
protected void onPreExecute() {
if (mOnBefore != null)
mOnBefore.call();
}
@Override
protected Void doInBackground(Void... params) {
try {
if (mDelay != 0) {
Thread.sleep(mDelay);
}
mCallable.call();
return null;
}
catch (Throwable ex) {
Log.e(TAG, "Exception caught: " + ex.toString());
mException = ex;
return null;
}
}
@Override
protected void onPostExecute(Void result) {
if (context != null) {
if (mException != null) {
if (mOnError != null)
mOnError.call(mException);
if (mOnAfter != null)
mOnAfter.call();
}
else {
if (mOnSuccess != null)
mOnSuccess.call();
if (mOnAfter != null)
mOnAfter.call();
}
}
else {
Log.w(TAG, "Context is null");
}
}
});
}
/** Sets the delay value, in milliseconds, before starting the task.
* @param delay delay value, in milliseconds
* @return
*/
public ParameterlessTask delayed(long delay) {
mDelay = delay;
return this;
}
/**
* Sets operation that will be called before execution of the background task
* @param onBefore
* @return
*/
public ParameterlessTask onBefore(Action0 onBefore) {
mOnBefore = onBefore;
return this;
}
/**
* Sets operation that will be called when the background task completed successfully
* @param onSuccess
* @return
*/
public ParameterlessTask onSuccess(Action0 onSuccess) {
mOnSuccess = onSuccess;
return this;
}
/**
* Sets operation that will be called if exception thrown in the background task
* @param onError
* @return
*/
public ParameterlessTask onError(Action<Throwable> onError) {
mOnError = onError;
return this;
}
/**
* Can be called anyway after the background task (after onSuccess or onError)
* @param onAfter
* @return
*/
public ParameterlessTask onAfter(Action0 onAfter) {
mOnAfter = onAfter;
return this;
}
}
public class ParametrizedTask<T> extends Task {
private static final String TAG = ParametrizedTask.class.getSimpleName();
protected Callable<T> mCallable = null;
protected Action0 mOnBefore = null;
protected Action<T> mOnSuccess = null;
protected Action<Throwable> mOnError = null;
protected Action0 mOnAfter = null;
protected long mDelay = 0;
/**
* Executes task and passes result within specified context.
* @param context
*/
public void execute(Context context) {
AsyncTaskCompat.executeParallel(
new AsyncTask<Void, Void, T>() {
private Throwable mException = null;
@Override
protected void onPreExecute() {
if (mOnBefore != null)
mOnBefore.call();
}
@Override
protected T doInBackground(Void... params) {
try {
if (mDelay != 0) {
Thread.sleep(mDelay);
}
return mCallable.call();
}
catch (Throwable ex) {
Log.e(TAG, "Exception caught: " + ex.toString());
mException = ex;
return null;
}
}
@Override
protected void onPostExecute(T result) {
if (context != null) {
if (mException != null) {
if (mOnError != null)
mOnError.call(mException);
if (mOnAfter != null)
mOnAfter.call();
}
else {
if (mOnSuccess != null)
mOnSuccess.call(result);
if (mOnAfter != null)
mOnAfter.call();
}
}
else {
Log.w(TAG, "Context is null");
}
}
});
}
/** Sets the delay value, in milliseconds, before starting the task.
* @param delay delay value, in milliseconds
* @return
*/
public ParametrizedTask<T> delayed(long delay) {
mDelay = delay;
return this;
}
/**
* Sets operation that will be called before execution of the background task
* @param onBefore
* @return
*/
public ParametrizedTask<T> onBefore(Action0 onBefore) {
mOnBefore = onBefore;
return this;
}
/**
* Sets operation that will be called when the background task completed successfully
* @param onSuccess
* @return
*/
public ParametrizedTask<T> onSuccess(Action<T> onSuccess) {
mOnSuccess = onSuccess;
return this;
}
/**
* Sets operation that will be called if exception thrown in the background task
* @param onError
* @return
*/
public ParametrizedTask<T> onError(Action<Throwable> onError) {
mOnError = onError;
return this;
}
/**
* Can be called anyway after the background task (after onSuccess or onError)
* @param onAfter
* @return
*/
public ParametrizedTask<T> onAfter(Action0 onAfter) {
mOnAfter = onAfter;
return this;
}
}
public class Task {
public static <T> ParametrizedTask<T> create(Callable<T> callable) {
ParametrizedTask<T> task = new ParametrizedTask<>();
task.mCallable = callable;
return task;
}
public static ParameterlessTask create(Callable0 callable) {
ParameterlessTask task = new ParameterlessTask();
task.mCallable = callable;
return task;
}
public interface Action<T> {
void call(T param);
}
public interface Action0 {
void call();
}
public interface Callable<T> {
T call() throws Exception;
}
public interface Callable0 {
void call() throws Exception;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment