diff --git a/checkstyle_suppressions.xml b/checkstyle_suppressions.xml
index 1bfebbe013..b966bcc929 100644
--- a/checkstyle_suppressions.xml
+++ b/checkstyle_suppressions.xml
@@ -8,6 +8,7 @@
+
diff --git a/glide/build.gradle b/glide/build.gradle
index 004bd95bec..7c70fd95b9 100644
--- a/glide/build.gradle
+++ b/glide/build.gradle
@@ -10,11 +10,12 @@ static def getAndroidPathsForJar() {
// The paths of Android projects that should be included only in Javadoc, not in the jar.
static def getAndroidPathsForJavadoc() {
[
+ ':integration:concurrent',
+ ':integration:gifencoder',
':integration:okhttp',
':integration:okhttp3',
- ':integration:volley',
- ':integration:gifencoder',
':integration:recyclerview',
+ ':integration:volley',
]
}
diff --git a/gradle.properties b/gradle.properties
index c8c1dc88d8..8058bbb2e3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -17,6 +17,7 @@ POM_DEVELOPER_NAME=Sam Judd
POM_DEVELOPER_EMAIL=judds@google.com
ANDROID_SUPPORT_VERSION=27.1.1
ANDROID_X_VERSION=1.0.0
+ANDROID_X_FUTURES_VERSION=1.0.0-rc01
ANDROIDX_TEST_VERSION=1.1.0
VOLLEY_VERSION=1.1.0
OK_HTTP_VERSION=3.9.1
@@ -33,7 +34,7 @@ TRUTH_VERSION=0.45
JSR_305_VERSION=3.0.2
AUTO_SERVICE_VERSION=1.0-rc3
JAVAPOET_VERSION=1.9.0
-GUAVA_VERSION=27.0.1-android
+GUAVA_VERSION=28.1-android
PMD_VERSION=6.0.0
FINDBUGS_VERSION=3.0.0
diff --git a/integration/concurrent/build.gradle b/integration/concurrent/build.gradle
new file mode 100644
index 0000000000..a7f0ef332d
--- /dev/null
+++ b/integration/concurrent/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'com.android.library'
+
+dependencies {
+ implementation project(':library')
+ implementation "com.google.guava:guava:${GUAVA_VERSION}"
+ implementation "androidx.concurrent:concurrent-futures:${ANDROID_X_FUTURES_VERSION}"
+
+ testImplementation "com.google.truth:truth:${TRUTH_VERSION}"
+ testImplementation "junit:junit:${JUNIT_VERSION}"
+ testImplementation "org.robolectric:robolectric:${ROBOLECTRIC_VERSION}"
+ testImplementation "androidx.legacy:legacy-support-v4:${ANDROID_X_VERSION}"
+}
+
+android {
+ compileSdkVersion COMPILE_SDK_VERSION as int
+
+ defaultConfig {
+ minSdkVersion MIN_SDK_VERSION as int
+ targetSdkVersion TARGET_SDK_VERSION as int
+
+ versionName = VERSION_NAME as String
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+}
+
+apply from: "${rootProject.projectDir}/scripts/upload.gradle"
diff --git a/integration/concurrent/gradle.properties b/integration/concurrent/gradle.properties
new file mode 100644
index 0000000000..0964795fce
--- /dev/null
+++ b/integration/concurrent/gradle.properties
@@ -0,0 +1,4 @@
+POM_NAME=Glide Concurrent Integration
+POM_ARTIFACT_ID=concurrent-integration
+POM_PACKAGING=aar
+POM_DESCRIPTION=An integration library for using Glide with ListenableFutures
diff --git a/integration/concurrent/src/main/AndroidManifest.xml b/integration/concurrent/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..92c8e1f5d7
--- /dev/null
+++ b/integration/concurrent/src/main/AndroidManifest.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/integration/concurrent/src/main/java/com/bumptech/glide/integration/concurrent/GlideFutures.java b/integration/concurrent/src/main/java/com/bumptech/glide/integration/concurrent/GlideFutures.java
new file mode 100644
index 0000000000..91cb9357bd
--- /dev/null
+++ b/integration/concurrent/src/main/java/com/bumptech/glide/integration/concurrent/GlideFutures.java
@@ -0,0 +1,82 @@
+package com.bumptech.glide.integration.concurrent;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.concurrent.futures.CallbackToFutureAdapter;
+import androidx.concurrent.futures.CallbackToFutureAdapter.Completer;
+import androidx.concurrent.futures.CallbackToFutureAdapter.Resolver;
+import com.bumptech.glide.RequestBuilder;
+import com.bumptech.glide.load.DataSource;
+import com.bumptech.glide.load.engine.GlideException;
+import com.bumptech.glide.request.FutureTarget;
+import com.bumptech.glide.request.RequestListener;
+import com.bumptech.glide.request.target.Target;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+
+/** Utilities for getting ListenableFutures out of Glide. */
+public final class GlideFutures {
+
+ /**
+ * Convert a pending load request into a ListenableFuture.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * ListenableFuture image =
+ * GlideFutures.submit(requestManager.asFile().load(url));
+ * }
+ *
+ * @param requestBuilder A request builder for the resource to load. It must be tied to an
+ * application Glide instance, and must not have a listener set.
+ */
+ public static ListenableFuture submit(final RequestBuilder requestBuilder) {
+ return CallbackToFutureAdapter.getFuture(
+ new Resolver() {
+ @Override
+ public Object attachCompleter(@NonNull Completer completer) {
+ GlideLoadingListener listener = new GlideLoadingListener<>(completer);
+ final FutureTarget futureTarget = requestBuilder.listener(listener).submit();
+ completer.addCancellationListener(
+ new Runnable() {
+ @Override
+ public void run() {
+ futureTarget.cancel(/*mayInterruptIfRunning=*/ true);
+ }
+ },
+ MoreExecutors.directExecutor());
+ return listener;
+ }
+ });
+ }
+
+ /** Listener to convert Glide load results into ListenableFutures. */
+ private static final class GlideLoadingListener implements RequestListener {
+
+ private final Completer completer;
+
+ GlideLoadingListener(Completer completer) {
+ this.completer = completer;
+ }
+
+ @Override
+ public boolean onLoadFailed(
+ @Nullable GlideException e, Object model, Target target, boolean isFirst) {
+ completer.setException(e != null ? e : new RuntimeException("Unknown error"));
+ return true;
+ }
+
+ @Override
+ public boolean onResourceReady(
+ T resource, Object model, Target target, DataSource dataSource, boolean isFirst) {
+ try {
+ completer.set(resource);
+ } catch (Throwable t) {
+ completer.setException(t);
+ }
+ return true;
+ }
+ }
+
+ private GlideFutures() {}
+}
diff --git a/settings.gradle b/settings.gradle
index 360b59b474..a1fab3b677 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -20,11 +20,12 @@ include ':samples:gallery'
include ':samples:contacturi'
include ':samples:imgur'
include ':integration'
-include ':integration:volley'
+include ':integration:concurrent'
+include ':integration:gifencoder'
include ':integration:okhttp'
include ':integration:okhttp3'
-include ':integration:gifencoder'
include ':integration:recyclerview'
+include ':integration:volley'
include ':testutil'
rootProject.name = 'glide-parent'