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'