Skip to content

Commit

Permalink
Add integration library for use with Guava's ListenableFuture class.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 266481039
  • Loading branch information
sjudd authored and glide-copybara-robot committed Aug 30, 2019
1 parent 9bb2c19 commit 9fb1036
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 5 deletions.
1 change: 1 addition & 0 deletions checkstyle_suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<suppress files=".*[/\\]library[/\\]src[/\\]main[/\\]java[/\\]com[/\\]bumptech[/\\]glide[/\\]util[/\\]CachedHashCodeArrayMap.java" checks="EqualsHashCodeCheck"/>
<suppress files=".*[/\\]library[/\\]test[/\\]src[/\\]test[/\\].*" checks="Javadoc.*"/>
<suppress files=".*[/\\]annotation[/\\]compiler[/\\]test[/\\]src[/\\]test[/\\]resources[/\\].*" checks=".*"/>
<suppress files=".*[/\\]integration[/\\]concurrent[/\\]src[/\\]test[/\\].*" checks=".*"/>
<suppress files=".*[/\\]instrumentation[/\\]src[/\\].*" checks="Javadoc.*"/>
<suppress files=".*[/\\]instrumentation[/\\]src[/\\]androidTest[/\\].*" checks="Javadoc.*"/>
<suppress files=".*[/\\]instrumentation[/\\]src[/\\]androidTest[/\\].*[/\\]ResourceIds" checks=".*"/>
Expand Down
5 changes: 3 additions & 2 deletions glide/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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',
]
}

Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ POM_DEVELOPER_NAME=Sam Judd
POM_DEVELOPER_EMAIL=[email protected]
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
Expand All @@ -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
Expand Down
30 changes: 30 additions & 0 deletions integration/concurrent/build.gradle
Original file line number Diff line number Diff line change
@@ -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"
4 changes: 4 additions & 0 deletions integration/concurrent/gradle.properties
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions integration/concurrent/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<manifest
package="com.bumptech.glide.integration.concurrent">

<application>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -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.
*
* <p>Sample code:
*
* <pre>{@code
* ListenableFuture<File> image =
* GlideFutures.submit(requestManager.asFile().load(url));
* }</pre>
*
* @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 <T> ListenableFuture<T> submit(final RequestBuilder<T> requestBuilder) {
return CallbackToFutureAdapter.getFuture(
new Resolver<T>() {
@Override
public Object attachCompleter(@NonNull Completer<T> completer) {
GlideLoadingListener<T> listener = new GlideLoadingListener<>(completer);
final FutureTarget<T> 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<T> implements RequestListener<T> {

private final Completer<T> completer;

GlideLoadingListener(Completer<T> completer) {
this.completer = completer;
}

@Override
public boolean onLoadFailed(
@Nullable GlideException e, Object model, Target<T> target, boolean isFirst) {
completer.setException(e != null ? e : new RuntimeException("Unknown error"));
return true;
}

@Override
public boolean onResourceReady(
T resource, Object model, Target<T> target, DataSource dataSource, boolean isFirst) {
try {
completer.set(resource);
} catch (Throwable t) {
completer.setException(t);
}
return true;
}
}

private GlideFutures() {}
}
5 changes: 3 additions & 2 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'

0 comments on commit 9fb1036

Please sign in to comment.