提交 93289994 编写于 作者: A adrianv 提交者: Sam Judd

Support multiple listeners in a Glide request.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=191378721
上级 a683e04d
...@@ -34,6 +34,8 @@ import com.bumptech.glide.util.Synthetic; ...@@ -34,6 +34,8 @@ import com.bumptech.glide.util.Synthetic;
import com.bumptech.glide.util.Util; import com.bumptech.glide.util.Util;
import java.io.File; import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/** /**
* A generic class that can handle setting options and staring loads for generic resource types. * A generic class that can handle setting options and staring loads for generic resource types.
...@@ -66,7 +68,7 @@ public class RequestBuilder<TranscodeType> implements Cloneable, ...@@ -66,7 +68,7 @@ public class RequestBuilder<TranscodeType> implements Cloneable,
@Nullable private Object model; @Nullable private Object model;
// model may occasionally be null, so to enforce that load() was called, put a boolean rather // model may occasionally be null, so to enforce that load() was called, put a boolean rather
// than relying on model not to be null. // than relying on model not to be null.
@Nullable private RequestListener<TranscodeType> requestListener; @Nullable private List<RequestListener<TranscodeType>> requestListeners;
@Nullable private RequestBuilder<TranscodeType> thumbnailBuilder; @Nullable private RequestBuilder<TranscodeType> thumbnailBuilder;
@Nullable private RequestBuilder<TranscodeType> errorBuilder; @Nullable private RequestBuilder<TranscodeType> errorBuilder;
@Nullable private Float thumbSizeMultiplier; @Nullable private Float thumbSizeMultiplier;
...@@ -144,6 +146,9 @@ public class RequestBuilder<TranscodeType> implements Cloneable, ...@@ -144,6 +146,9 @@ public class RequestBuilder<TranscodeType> implements Cloneable,
* instance of an exception handler per type of request (usually activity/fragment) rather than * instance of an exception handler per type of request (usually activity/fragment) rather than
* pass one in per request to avoid some redundant object allocation. * pass one in per request to avoid some redundant object allocation.
* *
* <p>Subsequent calls to this method will replace previously set listeners. To set multiple
* listeners, use {@link #addListener} instead.
*
* @param requestListener The request listener to use. * @param requestListener The request listener to use.
* @return This request builder. * @return This request builder.
*/ */
...@@ -152,8 +157,27 @@ public class RequestBuilder<TranscodeType> implements Cloneable, ...@@ -152,8 +157,27 @@ public class RequestBuilder<TranscodeType> implements Cloneable,
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public RequestBuilder<TranscodeType> listener( public RequestBuilder<TranscodeType> listener(
@Nullable RequestListener<TranscodeType> requestListener) { @Nullable RequestListener<TranscodeType> requestListener) {
this.requestListener = requestListener; this.requestListeners = null;
return addListener(requestListener);
}
/**
* Adds a {@link RequestListener}. If called multiple times, all passed
* {@link RequestListener listeners} will be called in order.
*
* @param requestListener The request listener to use. If {@code null}, this method is a noop.
* @return This request builder.
*/
@NonNull
@CheckResult
public RequestBuilder<TranscodeType> addListener(
@Nullable RequestListener<TranscodeType> requestListener) {
if (requestListener != null) {
if (this.requestListeners == null) {
this.requestListeners = new ArrayList<>();
}
this.requestListeners.add(requestListener);
}
return this; return this;
} }
...@@ -1041,7 +1065,7 @@ public class RequestBuilder<TranscodeType> implements Cloneable, ...@@ -1041,7 +1065,7 @@ public class RequestBuilder<TranscodeType> implements Cloneable,
priority, priority,
target, target,
targetListener, targetListener,
requestListener, requestListeners,
requestCoordinator, requestCoordinator,
glideContext.getEngine(), glideContext.getEngine(),
transitionOptions.getTransitionFactory()); transitionOptions.getTransitionFactory());
......
...@@ -24,6 +24,7 @@ import com.bumptech.glide.util.Synthetic; ...@@ -24,6 +24,7 @@ import com.bumptech.glide.util.Synthetic;
import com.bumptech.glide.util.Util; import com.bumptech.glide.util.Util;
import com.bumptech.glide.util.pool.FactoryPools; import com.bumptech.glide.util.pool.FactoryPools;
import com.bumptech.glide.util.pool.StateVerifier; import com.bumptech.glide.util.pool.StateVerifier;
import java.util.List;
/** /**
* A {@link Request} that loads a {@link com.bumptech.glide.load.engine.Resource} into a given * A {@link Request} that loads a {@link com.bumptech.glide.load.engine.Resource} into a given
...@@ -103,7 +104,7 @@ public final class SingleRequest<R> implements Request, ...@@ -103,7 +104,7 @@ public final class SingleRequest<R> implements Request,
private int overrideHeight; private int overrideHeight;
private Priority priority; private Priority priority;
private Target<R> target; private Target<R> target;
private RequestListener<R> requestListener; @Nullable private List<RequestListener<R>> requestListeners;
private Engine engine; private Engine engine;
private TransitionFactory<? super R> animationFactory; private TransitionFactory<? super R> animationFactory;
private Resource<R> resource; private Resource<R> resource;
...@@ -127,7 +128,7 @@ public final class SingleRequest<R> implements Request, ...@@ -127,7 +128,7 @@ public final class SingleRequest<R> implements Request,
Priority priority, Priority priority,
Target<R> target, Target<R> target,
RequestListener<R> targetListener, RequestListener<R> targetListener,
RequestListener<R> requestListener, @Nullable List<RequestListener<R>> requestListeners,
RequestCoordinator requestCoordinator, RequestCoordinator requestCoordinator,
Engine engine, Engine engine,
TransitionFactory<? super R> animationFactory) { TransitionFactory<? super R> animationFactory) {
...@@ -147,7 +148,7 @@ public final class SingleRequest<R> implements Request, ...@@ -147,7 +148,7 @@ public final class SingleRequest<R> implements Request,
priority, priority,
target, target,
targetListener, targetListener,
requestListener, requestListeners,
requestCoordinator, requestCoordinator,
engine, engine,
animationFactory); animationFactory);
...@@ -171,7 +172,7 @@ public final class SingleRequest<R> implements Request, ...@@ -171,7 +172,7 @@ public final class SingleRequest<R> implements Request,
Priority priority, Priority priority,
Target<R> target, Target<R> target,
RequestListener<R> targetListener, RequestListener<R> targetListener,
RequestListener<R> requestListener, @Nullable List<RequestListener<R>> requestListeners,
RequestCoordinator requestCoordinator, RequestCoordinator requestCoordinator,
Engine engine, Engine engine,
TransitionFactory<? super R> animationFactory) { TransitionFactory<? super R> animationFactory) {
...@@ -185,7 +186,7 @@ public final class SingleRequest<R> implements Request, ...@@ -185,7 +186,7 @@ public final class SingleRequest<R> implements Request,
this.priority = priority; this.priority = priority;
this.target = target; this.target = target;
this.targetListener = targetListener; this.targetListener = targetListener;
this.requestListener = requestListener; this.requestListeners = requestListeners;
this.requestCoordinator = requestCoordinator; this.requestCoordinator = requestCoordinator;
this.engine = engine; this.engine = engine;
this.animationFactory = animationFactory; this.animationFactory = animationFactory;
...@@ -209,7 +210,7 @@ public final class SingleRequest<R> implements Request, ...@@ -209,7 +210,7 @@ public final class SingleRequest<R> implements Request,
overrideWidth = -1; overrideWidth = -1;
overrideHeight = -1; overrideHeight = -1;
target = null; target = null;
requestListener = null; requestListeners = null;
targetListener = null; targetListener = null;
requestCoordinator = null; requestCoordinator = null;
animationFactory = null; animationFactory = null;
...@@ -570,10 +571,18 @@ public final class SingleRequest<R> implements Request, ...@@ -570,10 +571,18 @@ public final class SingleRequest<R> implements Request,
isCallingCallbacks = true; isCallingCallbacks = true;
try { try {
if ((requestListener == null boolean anyListenerHandledUpdatingTarget = false;
|| !requestListener.onResourceReady(result, model, target, dataSource, isFirstResource)) if (requestListeners != null) {
&& (targetListener == null for (RequestListener<R> listener : requestListeners) {
|| !targetListener.onResourceReady(result, model, target, dataSource, isFirstResource))) { anyListenerHandledUpdatingTarget |=
listener.onResourceReady(result, model, target, dataSource, isFirstResource);
}
}
anyListenerHandledUpdatingTarget |=
targetListener != null
&& targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);
if (!anyListenerHandledUpdatingTarget) {
Transition<? super R> animation = Transition<? super R> animation =
animationFactory.build(dataSource, isFirstResource); animationFactory.build(dataSource, isFirstResource);
target.onResourceReady(result, animation); target.onResourceReady(result, animation);
...@@ -609,10 +618,18 @@ public final class SingleRequest<R> implements Request, ...@@ -609,10 +618,18 @@ public final class SingleRequest<R> implements Request,
isCallingCallbacks = true; isCallingCallbacks = true;
try { try {
//TODO: what if this is a thumbnail request? //TODO: what if this is a thumbnail request?
if ((requestListener == null boolean anyListenerHandledUpdatingTarget = false;
|| !requestListener.onLoadFailed(e, model, target, isFirstReadyResource())) if (requestListeners != null) {
&& (targetListener == null for (RequestListener<R> listener : requestListeners) {
|| !targetListener.onLoadFailed(e, model, target, isFirstReadyResource()))) { anyListenerHandledUpdatingTarget |=
listener.onLoadFailed(e, model, target, isFirstReadyResource());
}
}
anyListenerHandledUpdatingTarget |=
targetListener != null
&& targetListener.onLoadFailed(e, model, target, isFirstReadyResource());
if (!anyListenerHandledUpdatingTarget) {
setErrorPlaceholder(); setErrorPlaceholder();
} }
} finally { } finally {
...@@ -633,14 +650,19 @@ public final class SingleRequest<R> implements Request, ...@@ -633,14 +650,19 @@ public final class SingleRequest<R> implements Request,
&& requestOptions.equals(that.requestOptions) && requestOptions.equals(that.requestOptions)
&& priority == that.priority && priority == that.priority
// We do not want to require that RequestListeners implement equals/hashcode, so we don't // We do not want to require that RequestListeners implement equals/hashcode, so we don't
// compare them using equals(). We can however, at least assert that the request listener // compare them using equals(). We can however, at least assert that the same amount of
// is either present or not present in both requests. // request listeners are present in both requests
&& (requestListener != null && listenerCountEquals(this, that);
? that.requestListener != null : that.requestListener == null);
} }
return false; return false;
} }
private static boolean listenerCountEquals(SingleRequest<?> first, SingleRequest<?> second) {
int firstListenerCount = first.requestListeners == null ? 0 : first.requestListeners.size();
int secondListenerCount = second.requestListeners == null ? 0 : second.requestListeners.size();
return firstListenerCount == secondListenerCount;
}
private void logV(String message) { private void logV(String message) {
Log.v(TAG, message + " this: " + tag); Log.v(TAG, message + " this: " + tag);
} }
......
...@@ -2,16 +2,22 @@ package com.bumptech.glide; ...@@ -2,16 +2,22 @@ package com.bumptech.glide;
import static com.bumptech.glide.tests.BackgroundUtil.testInBackground; import static com.bumptech.glide.tests.BackgroundUtil.testInBackground;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA; import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.Application; import android.app.Application;
import android.widget.ImageView; import android.widget.ImageView;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.resource.SimpleResource;
import com.bumptech.glide.request.Request; import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.SingleRequest;
import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.target.ViewTarget; import com.bumptech.glide.request.target.ViewTarget;
import com.bumptech.glide.tests.BackgroundUtil.BackgroundTester; import com.bumptech.glide.tests.BackgroundUtil.BackgroundTester;
...@@ -20,6 +26,8 @@ import org.junit.Before; ...@@ -20,6 +26,8 @@ import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
...@@ -32,8 +40,12 @@ import org.robolectric.annotation.Config; ...@@ -32,8 +40,12 @@ import org.robolectric.annotation.Config;
public class RequestBuilderTest { public class RequestBuilderTest {
@Rule public TearDownGlide tearDownGlide = new TearDownGlide(); @Rule public TearDownGlide tearDownGlide = new TearDownGlide();
@Mock private RequestListener<Object> listener1;
@Mock private RequestListener<Object> listener2;
@Mock private Target<Object> target;
@Mock private GlideContext glideContext; @Mock private GlideContext glideContext;
@Mock private RequestManager requestManager; @Mock private RequestManager requestManager;
@Captor private ArgumentCaptor<SingleRequest<Object>> requestCaptor;
private Glide glide; private Glide glide;
private Application context; private Application context;
...@@ -57,12 +69,11 @@ public class RequestBuilderTest { ...@@ -57,12 +69,11 @@ public class RequestBuilderTest {
@Test @Test
public void testDoesNotThrowWithNullModelWhenRequestIsBuilt() { public void testDoesNotThrowWithNullModelWhenRequestIsBuilt() {
getNullModelRequest().into(mock(Target.class)); getNullModelRequest().into(target);
} }
@Test @Test
public void testAddsNewRequestToRequestTracker() { public void testAddsNewRequestToRequestTracker() {
Target<Object> target = mock(Target.class);
getNullModelRequest().into(target); getNullModelRequest().into(target);
verify(requestManager).track(eq(target), isA(Request.class)); verify(requestManager).track(eq(target), isA(Request.class));
...@@ -71,7 +82,6 @@ public class RequestBuilderTest { ...@@ -71,7 +82,6 @@ public class RequestBuilderTest {
@Test @Test
public void testRemovesPreviousRequestFromRequestTracker() { public void testRemovesPreviousRequestFromRequestTracker() {
Request previous = mock(Request.class); Request previous = mock(Request.class);
Target<Object> target = mock(Target.class);
when(target.getRequest()).thenReturn(previous); when(target.getRequest()).thenReturn(previous);
getNullModelRequest().into(target); getNullModelRequest().into(target);
...@@ -112,6 +122,35 @@ public class RequestBuilderTest { ...@@ -112,6 +122,35 @@ public class RequestBuilderTest {
}); });
} }
@Test
public void testMultipleRequestListeners() {
getNullModelRequest().addListener(listener1).addListener(listener2).into(target);
verify(requestManager).track(any(Target.class), requestCaptor.capture());
requestCaptor.getValue().onResourceReady(new SimpleResource<>(new Object()), DataSource.LOCAL);
verify(listener1)
.onResourceReady(
any(), any(), isA(Target.class), isA(DataSource.class), anyBoolean());
verify(listener2)
.onResourceReady(
any(), any(), isA(Target.class), isA(DataSource.class), anyBoolean());
}
@Test
public void testListenerApiOverridesListeners() {
getNullModelRequest().addListener(listener1).listener(listener2).into(target);
verify(requestManager).track(any(Target.class), requestCaptor.capture());
requestCaptor.getValue().onResourceReady(new SimpleResource<>(new Object()), DataSource.LOCAL);
// The #listener API removes any previous listeners, so the first listener should not be called.
verify(listener1, never())
.onResourceReady(
any(), any(), isA(Target.class), isA(DataSource.class), anyBoolean());
verify(listener2)
.onResourceReady(
any(), any(), isA(Target.class), isA(DataSource.class), anyBoolean());
}
private RequestBuilder<Object> getNullModelRequest() { private RequestBuilder<Object> getNullModelRequest() {
when(glideContext.buildImageViewTarget(isA(ImageView.class), isA(Class.class))) when(glideContext.buildImageViewTarget(isA(ImageView.class), isA(Class.class)))
.thenReturn(mock(ViewTarget.class)); .thenReturn(mock(ViewTarget.class));
......
...@@ -46,6 +46,8 @@ import java.util.Map; ...@@ -46,6 +46,8 @@ import java.util.Map;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
...@@ -57,9 +59,12 @@ import org.robolectric.annotation.Config; ...@@ -57,9 +59,12 @@ import org.robolectric.annotation.Config;
public class SingleRequestTest { public class SingleRequestTest {
private SingleRequestBuilder builder; private SingleRequestBuilder builder;
@Mock private RequestListener<List> listener1;
@Mock private RequestListener<List> listener2;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this);
builder = new SingleRequestBuilder(); builder = new SingleRequestBuilder();
} }
...@@ -72,31 +77,31 @@ public class SingleRequestTest { ...@@ -72,31 +77,31 @@ public class SingleRequestTest {
@Test @Test
public void testCanHandleNullResources() { public void testCanHandleNullResources() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request = builder.addRequestListener(listener1).build();
request.onResourceReady(null, DataSource.LOCAL); request.onResourceReady(null, DataSource.LOCAL);
assertTrue(request.isFailed()); assertTrue(request.isFailed());
verify(builder.requestListener).onLoadFailed(isAGlideException(), isA(Number.class), verify(listener1).onLoadFailed(isAGlideException(), isA(Number.class),
eq(builder.target), anyBoolean()); eq(builder.target), anyBoolean());
} }
@Test @Test
public void testCanHandleEmptyResources() { public void testCanHandleEmptyResources() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request = builder.addRequestListener(listener1).build();
when(builder.resource.get()).thenReturn(null); when(builder.resource.get()).thenReturn(null);
request.onResourceReady(builder.resource, DataSource.REMOTE); request.onResourceReady(builder.resource, DataSource.REMOTE);
assertTrue(request.isFailed()); assertTrue(request.isFailed());
verify(builder.engine).release(eq(builder.resource)); verify(builder.engine).release(eq(builder.resource));
verify(builder.requestListener).onLoadFailed(isAGlideException(), any(Number.class), verify(listener1).onLoadFailed(isAGlideException(), any(Number.class),
eq(builder.target), anyBoolean()); eq(builder.target), anyBoolean());
} }
@Test @Test
public void testCanHandleNonConformingResources() { public void testCanHandleNonConformingResources() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request = builder.addRequestListener(listener1).build();
when(((Resource) (builder.resource)).get()) when(((Resource) (builder.resource)).get())
.thenReturn("Invalid mocked String, this should be a List"); .thenReturn("Invalid mocked String, this should be a List");
...@@ -104,7 +109,7 @@ public class SingleRequestTest { ...@@ -104,7 +109,7 @@ public class SingleRequestTest {
assertTrue(request.isFailed()); assertTrue(request.isFailed());
verify(builder.engine).release(eq(builder.resource)); verify(builder.engine).release(eq(builder.resource));
verify(builder.requestListener).onLoadFailed(isAGlideException(), any(Number.class), verify(listener1).onLoadFailed(isAGlideException(), any(Number.class),
eq(builder.target), anyBoolean()); eq(builder.target), anyBoolean());
} }
...@@ -453,18 +458,21 @@ public class SingleRequestTest { ...@@ -453,18 +458,21 @@ public class SingleRequestTest {
@Test @Test
public void testCallsTargetOnResourceReadyIfNoRequestListener() { public void testCallsTargetOnResourceReadyIfNoRequestListener() {
SingleRequest<List> request = builder SingleRequest<List> request = builder.build();
.setRequestListener(null)
.build();
request.onResourceReady(builder.resource, DataSource.LOCAL); request.onResourceReady(builder.resource, DataSource.LOCAL);
verify(builder.target).onResourceReady(eq(builder.result), anyTransition()); verify(builder.target).onResourceReady(eq(builder.result), anyTransition());
} }
@Test @Test
public void testCallsTargetOnResourceReadyIfRequestListenerReturnsFalse() { public void testCallsTargetOnResourceReadyIfAllRequestListenersReturnFalse() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request =
when(builder.requestListener builder.addRequestListener(listener1).addRequestListener(listener2).build();
when(listener1
.onResourceReady(any(List.class), any(Number.class), eq(builder.target), isADataSource(),
anyBoolean())).thenReturn(false);
when(listener2
.onResourceReady(any(List.class), any(Number.class), eq(builder.target), isADataSource(), .onResourceReady(any(List.class), any(Number.class), eq(builder.target), isADataSource(),
anyBoolean())).thenReturn(false); anyBoolean())).thenReturn(false);
request.onResourceReady(builder.resource, DataSource.LOCAL); request.onResourceReady(builder.resource, DataSource.LOCAL);
...@@ -473,9 +481,14 @@ public class SingleRequestTest { ...@@ -473,9 +481,14 @@ public class SingleRequestTest {
} }
@Test @Test
public void testDoesNotCallTargetOnResourceReadyIfRequestListenerReturnsTrue() { public void testDoesNotCallTargetOnResourceReadyIfAnyRequestListenerReturnsTrue() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request =
when(builder.requestListener builder.addRequestListener(listener1).addRequestListener(listener2).build();
when(listener1
.onResourceReady(any(List.class), any(Number.class), eq(builder.target), isADataSource(),
anyBoolean())).thenReturn(false);
when(listener1
.onResourceReady(any(List.class), any(Number.class), eq(builder.target), isADataSource(), .onResourceReady(any(List.class), any(Number.class), eq(builder.target), isADataSource(),
anyBoolean())).thenReturn(true); anyBoolean())).thenReturn(true);
request.onResourceReady(builder.resource, DataSource.REMOTE); request.onResourceReady(builder.resource, DataSource.REMOTE);
...@@ -485,18 +498,21 @@ public class SingleRequestTest { ...@@ -485,18 +498,21 @@ public class SingleRequestTest {
@Test @Test
public void testCallsTargetOnExceptionIfNoRequestListener() { public void testCallsTargetOnExceptionIfNoRequestListener() {
SingleRequest<List> request = builder SingleRequest<List> request = builder.build();
.setRequestListener(null)
.build();
request.onLoadFailed(new GlideException("test")); request.onLoadFailed(new GlideException("test"));
verify(builder.target).onLoadFailed(eq(builder.errorDrawable)); verify(builder.target).onLoadFailed(eq(builder.errorDrawable));
} }
@Test @Test
public void testCallsTargetOnExceptionIfRequestListenerReturnsFalse() { public void testCallsTargetOnExceptionIfAllRequestListenersReturnFalse() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request =
when(builder.requestListener.onLoadFailed(isAGlideException(), any(Number.class), builder.addRequestListener(listener1).addRequestListener(listener2).build();
when(listener1.onLoadFailed(isAGlideException(), any(Number.class),
eq(builder.target), anyBoolean()))
.thenReturn(false);
when(listener2.onLoadFailed(isAGlideException(), any(Number.class),
eq(builder.target), anyBoolean())) eq(builder.target), anyBoolean()))
.thenReturn(false); .thenReturn(false);
request.onLoadFailed(new GlideException("test")); request.onLoadFailed(new GlideException("test"));
...@@ -505,9 +521,14 @@ public class SingleRequestTest { ...@@ -505,9 +521,14 @@ public class SingleRequestTest {
} }
@Test @Test
public void testDoesNotCallTargetOnExceptionIfRequestListenerReturnsTrue() { public void testDoesNotCallTargetOnExceptionIfAnyRequestListenerReturnsTrue() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request =
when(builder.requestListener.onLoadFailed(isAGlideException(), any(Number.class), builder.addRequestListener(listener1).addRequestListener(listener2).build();
when(listener1.onLoadFailed(isAGlideException(), any(Number.class),
eq(builder.target), anyBoolean()))
.thenReturn(false);
when(listener2.onLoadFailed(isAGlideException(), any(Number.class),
eq(builder.target), anyBoolean())) eq(builder.target), anyBoolean()))
.thenReturn(true); .thenReturn(true);
...@@ -518,37 +539,37 @@ public class SingleRequestTest { ...@@ -518,37 +539,37 @@ public class SingleRequestTest {
@Test @Test
public void testRequestListenerIsCalledWithResourceResult() { public void testRequestListenerIsCalledWithResourceResult() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request = builder.addRequestListener(listener1).build();
request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE); request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE);
verify(builder.requestListener) verify(listener1)
.onResourceReady(eq(builder.result), any(Number.class), isAListTarget(), isADataSource(), .onResourceReady(eq(builder.result), any(Number.class), isAListTarget(), isADataSource(),
anyBoolean()); anyBoolean());
} }
@Test @Test
public void testRequestListenerIsCalledWithModel() { public void testRequestListenerIsCalledWithModel() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request = builder.addRequestListener(listener1).build();
request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE); request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE);
verify(builder.requestListener) verify(listener1)
.onResourceReady(any(List.class), eq(builder.model), isAListTarget(), isADataSource(), .onResourceReady(any(List.class), eq(builder.model), isAListTarget(), isADataSource(),
anyBoolean()); anyBoolean());
} }
@Test @Test
public void testRequestListenerIsCalledWithTarget() { public void testRequestListenerIsCalledWithTarget() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request = builder.addRequestListener(listener1).build();
request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE); request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE);
verify(builder.requestListener) verify(listener1)
.onResourceReady(any(List.class), any(Number.class), eq(builder.target), isADataSource(), .onResourceReady(any(List.class), any(Number.class), eq(builder.target), isADataSource(),
anyBoolean()); anyBoolean());
} }
@Test @Test
public void testRequestListenerIsCalledWithLoadedFromMemoryIfLoadCompletesSynchronously() { public void testRequestListenerIsCalledWithLoadedFromMemoryIfLoadCompletesSynchronously() {
final SingleRequest<List> request = builder.build(); SingleRequest<List> request = builder.addRequestListener(listener1).build();
when(builder.engine when(builder.engine
.load( .load(
...@@ -580,7 +601,7 @@ public class SingleRequestTest { ...@@ -580,7 +601,7 @@ public class SingleRequestTest {
request.begin(); request.begin();
request.onSizeReady(100, 100); request.onSizeReady(100, 100);
verify(builder.requestListener) verify(listener1)
.onResourceReady(eq(builder.result), any(Number.class), isAListTarget(), .onResourceReady(eq(builder.result), any(Number.class), isAListTarget(),
eq(DataSource.MEMORY_CACHE), anyBoolean()); eq(DataSource.MEMORY_CACHE), anyBoolean());
} }
...@@ -588,11 +609,11 @@ public class SingleRequestTest { ...@@ -588,11 +609,11 @@ public class SingleRequestTest {
@Test @Test
public void public void
testRequestListenerIsCalledWithNotLoadedFromMemoryCacheIfLoadCompletesAsynchronously() { testRequestListenerIsCalledWithNotLoadedFromMemoryCacheIfLoadCompletesAsynchronously() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request = builder.addRequestListener(listener1).build();
request.onSizeReady(100, 100); request.onSizeReady(100, 100);
request.onResourceReady(builder.resource, DataSource.LOCAL); request.onResourceReady(builder.resource, DataSource.LOCAL);
verify(builder.requestListener) verify(listener1)
.onResourceReady(eq(builder.result), any(Number.class), isAListTarget(), .onResourceReady(eq(builder.result), any(Number.class), isAListTarget(),
eq(DataSource.LOCAL), anyBoolean()); eq(DataSource.LOCAL), anyBoolean());
} }
...@@ -601,21 +622,22 @@ public class SingleRequestTest { ...@@ -601,21 +622,22 @@ public class SingleRequestTest {
public void testRequestListenerIsCalledWithIsFirstResourceIfNoRequestCoordinator() { public void testRequestListenerIsCalledWithIsFirstResourceIfNoRequestCoordinator() {
SingleRequest<List> request = builder SingleRequest<List> request = builder
.setRequestCoordinator(null) .setRequestCoordinator(null)
.addRequestListener(listener1)
.build(); .build();
request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE); request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE);
verify(builder.requestListener) verify(listener1)
.onResourceReady(eq(builder.result), any(Number.class), isAListTarget(), isADataSource(), .onResourceReady(eq(builder.result), any(Number.class), isAListTarget(), isADataSource(),
eq(true)); eq(true));
} }
@Test @Test
public void testRequestListenerIsCalledWithFirstImageIfRequestCoordinatorReturnsNoResourceSet() { public void testRequestListenerIsCalledWithFirstImageIfRequestCoordinatorReturnsNoResourceSet() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request = builder.addRequestListener(listener1).build();
when(builder.requestCoordinator.isAnyResourceSet()).thenReturn(false); when(builder.requestCoordinator.isAnyResourceSet()).thenReturn(false);
request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE); request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE);
verify(builder.requestListener) verify(listener1)
.onResourceReady(eq(builder.result), any(Number.class), isAListTarget(), isADataSource(), .onResourceReady(eq(builder.result), any(Number.class), isAListTarget(), isADataSource(),
eq(true)); eq(true));
} }
...@@ -623,11 +645,11 @@ public class SingleRequestTest { ...@@ -623,11 +645,11 @@ public class SingleRequestTest {
@Test @Test
public void public void
testRequestListenerIsCalledWithNotIsFirstRequestIfRequestCoordinatorReturnsResourceSet() { testRequestListenerIsCalledWithNotIsFirstRequestIfRequestCoordinatorReturnsResourceSet() {
SingleRequest<List> request = builder.build(); SingleRequest<List> request = builder.addRequestListener(listener1).build();
when(builder.requestCoordinator.isAnyResourceSet()).thenReturn(true); when(builder.requestCoordinator.isAnyResourceSet()).thenReturn(true);
request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE); request.onResourceReady(builder.resource, DataSource.DATA_DISK_CACHE);
verify(builder.requestListener) verify(listener1)
.onResourceReady(eq(builder.result), any(Number.class), isAListTarget(), .onResourceReady(eq(builder.result), any(Number.class), isAListTarget(),
isADataSource(), eq(false)); isADataSource(), eq(false));
} }
...@@ -872,13 +894,9 @@ public class SingleRequestTest { ...@@ -872,13 +894,9 @@ public class SingleRequestTest {
}); });
tester tester
.addEquivalenceGroup( .addEquivalenceGroup(
new SingleRequestBuilder(),
new SingleRequestBuilder(),
// Non-null request listeners are treated as equivalent, even if they're not equal. // Non-null request listeners are treated as equivalent, even if they're not equal.
new SingleRequestBuilder().setRequestListener(mock(RequestListener.class))) new SingleRequestBuilder().addRequestListener(listener1),
.addEquivalenceGroup( new SingleRequestBuilder().addRequestListener(listener2))
new SingleRequestBuilder().setRequestListener(null),
new SingleRequestBuilder().setRequestListener(null))
.addEquivalenceGroup( .addEquivalenceGroup(
new SingleRequestBuilder().setOverrideHeight(500), new SingleRequestBuilder().setOverrideHeight(500),
new SingleRequestBuilder().setOverrideHeight(500)) new SingleRequestBuilder().setOverrideHeight(500))
...@@ -911,7 +929,7 @@ public class SingleRequestTest { ...@@ -911,7 +929,7 @@ public class SingleRequestTest {
private Drawable errorDrawable = null; private Drawable errorDrawable = null;
private Drawable fallbackDrawable = null; private Drawable fallbackDrawable = null;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private RequestListener<List> requestListener = mock(RequestListener.class); private List<RequestListener<List>> requestListeners = new ArrayList<>();
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private final TransitionFactory<List> transitionFactory = mock(TransitionFactory.class); private final TransitionFactory<List> transitionFactory = mock(TransitionFactory.class);
private int overrideWidth = -1; private int overrideWidth = -1;
...@@ -971,8 +989,8 @@ public class SingleRequestTest { ...@@ -971,8 +989,8 @@ public class SingleRequestTest {
return this; return this;
} }
SingleRequestBuilder setRequestListener(RequestListener<List> requestListener) { SingleRequestBuilder addRequestListener(RequestListener<List> requestListener) {
this.requestListener = requestListener; this.requestListeners.add(requestListener);
return this; return this;
} }
...@@ -1022,7 +1040,7 @@ public class SingleRequestTest { ...@@ -1022,7 +1040,7 @@ public class SingleRequestTest {
priority, priority,
target, target,
/*targetListener=*/ null, /*targetListener=*/ null,
requestListener, requestListeners,
requestCoordinator, requestCoordinator,
engine, engine,
transitionFactory); transitionFactory);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册