#635 - Add the ability to cancel a task

This commit is contained in:
Joshua Soberg 2021-02-03 21:38:26 -05:00
parent bc8bcf834f
commit 7ab8eefce7

View file

@ -26,6 +26,8 @@ public abstract class UiBasedBackgroundTask<Result> {
@Nullable @Nullable
private Result awaitedResult; private Result awaitedResult;
private volatile boolean isCanceled = false;
/** @param failedResult The result to return if the task fails (throws an exception or returns null). */ /** @param failedResult The result to return if the task fails (throws an exception or returns null). */
public UiBasedBackgroundTask(@NonNull Result failedResult) { public UiBasedBackgroundTask(@NonNull Result failedResult) {
this.failedResult = failedResult; this.failedResult = failedResult;
@ -37,6 +39,10 @@ public abstract class UiBasedBackgroundTask<Result> {
* be stored until a new callback is set. */ * be stored until a new callback is set. */
public void setCallback(@Nullable UiCallback<Result> callback) { public void setCallback(@Nullable UiCallback<Result> callback) {
synchronized (callbackLock) { synchronized (callbackLock) {
// Don't bother doing anything if the task was canceled.
if (isCanceled()) {
return;
}
this.callback = callback; this.callback = callback;
// If we have an awaited result and are setting a new callback, publish the result immediately. // If we have an awaited result and are setting a new callback, publish the result immediately.
if (awaitedResult != null && callback != null) { if (awaitedResult != null && callback != null) {
@ -66,6 +72,10 @@ public abstract class UiBasedBackgroundTask<Result> {
} }
synchronized (callbackLock) { synchronized (callbackLock) {
// Don't bother issuing callback or storing result if this task is canceled.
if (isCanceled()) {
return;
}
if (callback != null) { if (callback != null) {
emitResultOnMainThread(callback, result); emitResultOnMainThread(callback, result);
} else { } else {
@ -81,6 +91,16 @@ public abstract class UiBasedBackgroundTask<Result> {
@NonNull @NonNull
protected abstract Result doInBackground() throws Exception; protected abstract Result doInBackground() throws Exception;
@AnyThread
public boolean isCanceled() {
return isCanceled;
}
@AnyThread
public void cancel() {
isCanceled = true;
}
@FunctionalInterface @FunctionalInterface
public interface UiCallback<Result> { public interface UiCallback<Result> {
@MainThread @MainThread