Skip to content

Commit a9b0374

Browse files
authored
initial commit
1 parent ae23fb3 commit a9b0374

File tree

11 files changed

+583
-0
lines changed

11 files changed

+583
-0
lines changed

AsyncTask/build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins {
2+
id 'java-library'
3+
}
4+
5+
java {
6+
sourceCompatibility = JavaVersion.VERSION_16
7+
targetCompatibility = JavaVersion.VERSION_16
8+
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package com.xcoder.tasks;
2+
3+
import java.util.Arrays;
4+
import java.util.concurrent.Callable;
5+
import java.util.concurrent.CompletableFuture;
6+
import java.util.concurrent.CompletionException;
7+
import java.util.concurrent.TimeUnit;
8+
import java.util.function.Function;
9+
10+
/**
11+
* AsyncTask is a convenience class for running asynchronous tasks.
12+
* This is java port of google play services Tasks api. This can be used in both android
13+
* and non-android projects. However, in android , targetSdkVersion should be >= 28.
14+
*
15+
* @param <T> The type of the result.
16+
*/
17+
public class AsyncTask<T> {
18+
public Exception exception;
19+
public T result;
20+
public boolean isSuccessful;
21+
private CompletableFuture<T> future;
22+
private OnCompleteCallback<T> completeCallback = call -> {};
23+
private OnErrorCallback errorCallback = e -> {};
24+
private OnSuccessCallback<T> successCallback = result -> {};
25+
26+
/**
27+
* Executes the task asynchronously. This method returns immediately. It takes a callable which
28+
* if returns the value, the task is considered successful. If the callable throws an exception,
29+
* the task is considered failed.
30+
*
31+
* @param callable the task to execute
32+
* @param <T> the type of the result
33+
* @return the call that can be used to get the result in future
34+
*/
35+
public static <T> AsyncTask<T> callAsync(Callable<T> callable) {
36+
AsyncTask<T> call = new AsyncTask<>();
37+
call.future = CompletableFuture.supplyAsync(() -> {
38+
try {
39+
Thread.sleep(10);
40+
return callable.call();
41+
} catch (Exception e) {
42+
throw new CompletionException(e);
43+
}
44+
}).whenComplete((t, throwable) -> {
45+
if (throwable == null) {
46+
call.result = t;
47+
call.isSuccessful = true;
48+
call.successCallback.onSuccess(t);
49+
} else {
50+
call.exception = (Exception) throwable;
51+
call.isSuccessful = false;
52+
call.errorCallback.onError((Exception) throwable);
53+
}
54+
call.completeCallback.onComplete(call);
55+
});
56+
return call;
57+
}
58+
59+
/**
60+
* Joins all the tasks and build a single task that is resultant of all the tasks.
61+
*
62+
* @param tasks the tasks to join
63+
* @return the joined task
64+
*/
65+
public static AsyncTask<?> allOf(AsyncTask<?>... tasks) {
66+
AsyncTask<?> task = new AsyncTask<>();
67+
CompletableFuture<?>[] array = Arrays.stream(tasks)
68+
.map((Function<AsyncTask<?>, CompletableFuture<?>>) asyncTask -> asyncTask.future)
69+
.toArray(CompletableFuture[]::new);
70+
CompletableFuture.allOf(array).whenComplete((unused, throwable) -> {
71+
task.completeCallback.onComplete(null);
72+
if (throwable == null) {
73+
task.isSuccessful = true;
74+
task.successCallback.onSuccess(null);
75+
} else {
76+
task.exception = (Exception) throwable;
77+
task.isSuccessful = false;
78+
task.errorCallback.onError((Exception) throwable);
79+
}
80+
});
81+
return task;
82+
}
83+
84+
/**
85+
* Executes the task asynchronously and sequentially one after another. If you have multiple nested tasks,
86+
* you can use this method to execute them sequentially.
87+
* @param function the function to execute
88+
* @param <R> the type of the result
89+
* @return the call that can be used to get the result in future
90+
*/
91+
public <R> AsyncTask<R> thenPerform(AsyncFunction<T, R> function) {
92+
AsyncTask<R> task = new AsyncTask<>();
93+
task.future = future.thenApplyAsync(t -> {
94+
try {
95+
return function.task(t);
96+
} catch (Exception e) {
97+
throw new CompletionException(e);
98+
}
99+
}).whenComplete((r, throwable) -> {
100+
if (throwable == null) {
101+
task.result = r;
102+
task.isSuccessful = true;
103+
task.successCallback.onSuccess(r);
104+
} else {
105+
task.exception = (Exception) throwable;
106+
task.isSuccessful = false;
107+
task.errorCallback.onError((Exception) throwable);
108+
}
109+
task.completeCallback.onComplete(task);
110+
});
111+
return task;
112+
}
113+
114+
/**
115+
* Returns the result of the task or wait if it is not yet completed.
116+
*
117+
* @param timeoutSeconds the maximum time (in seconds) to wait for the task to complete
118+
* @return The result
119+
* @throws Exception if the task failed or the timeout was reached.
120+
*/
121+
public T getResult(int timeoutSeconds) throws Exception {
122+
return future.get(timeoutSeconds, TimeUnit.SECONDS);
123+
}
124+
125+
126+
public AsyncTask<T> setOnSuccessCallback(OnSuccessCallback<T> onSuccessCallback) {
127+
this.successCallback = onSuccessCallback;
128+
return this;
129+
}
130+
131+
public AsyncTask<T> setOnErrorCallback(OnErrorCallback onErrorCallback) {
132+
this.errorCallback = onErrorCallback;
133+
return this;
134+
}
135+
136+
public void setOnCompleteCallback(OnCompleteCallback<T> onCompleteCallback) {
137+
this.completeCallback = onCompleteCallback;
138+
}
139+
140+
141+
public interface OnCompleteCallback<T> {
142+
void onComplete(AsyncTask<T> call);
143+
}
144+
145+
public interface OnSuccessCallback<T> {
146+
void onSuccess(T result);
147+
}
148+
149+
public interface OnErrorCallback {
150+
void onError(Exception e);
151+
}
152+
153+
/**
154+
* A function used to perform an asynchronous task in chain. To be used with {@link #thenPerform(AsyncFunction)} method
155+
* @param <T> the type of the input
156+
* @param <R> the type of the output
157+
*/
158+
@FunctionalInterface
159+
public interface AsyncFunction<T,R> {
160+
R task(T t) throws Exception;
161+
}
162+
}

build.gradle

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
2+
buildscript {
3+
repositories {
4+
google()
5+
mavenCentral()
6+
gradlePluginPortal()
7+
}
8+
dependencies {
9+
classpath 'com.google.gms:google-services:4.3.10'
10+
classpath 'com.android.tools.build:gradle:7.1.1'
11+
classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:0.14.0'
12+
// NOTE: Do not place your application dependencies here; they belong
13+
// in the individual module build.gradle files
14+
}
15+
}
16+
17+
allprojects {
18+
repositories {
19+
google()
20+
mavenCentral()
21+
maven {
22+
url 'https://jitpack.io'
23+
}
24+
}
25+
}
26+
27+
task clean(type: Delete) {
28+
delete rootProject.buildDir
29+
}

gradle.properties

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Project-wide Gradle settings.
2+
# IDE (e.g. Android Studio) users:
3+
# Gradle settings configured through the IDE *will override*
4+
# any settings specified in this file.
5+
# For more details on how to configure your build environment visit
6+
# http://www.gradle.org/docs/current/userguide/build_environment.html
7+
# Specifies the JVM arguments used for the daemon process.
8+
# The setting is particularly useful for tweaking memory settings.
9+
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10+
# When configured, Gradle will run in incubating parallel mode.
11+
# This option should only be used with decoupled projects. More details, visit
12+
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13+
# org.gradle.parallel=true
14+
# AndroidX package structure to make it clearer which packages are bundled with the
15+
# Android operating system, and which are packaged with your app"s APK
16+
# https://developer.android.com/topic/libraries/support-library/androidx-rn
17+
android.useAndroidX=true
18+
android.enableJetifier=true

gradle/wrapper/gradle-wrapper.jar

58.1 KB
Binary file not shown.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#Sun Feb 06 00:06:22 IST 2022
2+
distributionBase=GRADLE_USER_HOME
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
4+
distributionPath=wrapper/dists
5+
zipStorePath=wrapper/dists
6+
zipStoreBase=GRADLE_USER_HOME

0 commit comments

Comments
 (0)