/** * Start an image request using the specified image file. This is a convenience method for * calling {@link #load(Uri)}. * <p> * Passing {@code null} as a {@code file} will not trigger any request but will set a * placeholder, if one is specified. * <p> * Equivalent to calling {@link #load(Uri) load(Uri.fromFile(file))}. * * @see #load(Uri) * @see #load(String) * @see #load(int) */ @NonNull public RequestCreator load(@Nullable File file) { if (file == null) { return new RequestCreator(this, null, 0); } return load(Uri.fromFile(file)); }
@Test public void intoImageViewWithQuickMemoryCacheCheckDoesNotSubmit() { PlatformLruCache cache = new PlatformLruCache(0); Picasso picasso = spy(new Picasso(RuntimeEnvironment.application, mock(Dispatcher.class), UNUSED_CALL_FACTORY, null, cache, null, NO_TRANSFORMERS, NO_HANDLERS, mock(Stats.class), ARGB_8888, false, false)); doReturn(bitmap).when(picasso).quickMemoryCacheCheck(URI_KEY_1); ImageView target = mockImageViewTarget(); Callback callback = mockCallback(); new RequestCreator(picasso, URI_1, 0).into(target, callback); verify(target).setImageDrawable(any(PicassoDrawable.class)); verify(callback).onSuccess(); verify(picasso).cancelRequest(target); verify(picasso, never()).enqueueAndSubmit(any(Action.class)); }
@Override public void handleMessage(Message msg) { switch (msg.what) { case HUNTER_COMPLETE: { BitmapHunter hunter = (BitmapHunter) msg.obj; hunter.picasso.complete(hunter); break; } case REQUEST_BATCH_RESUME: @SuppressWarnings("unchecked") List<Action> batch = (List<Action>) msg.obj; //noinspection ForLoopReplaceableByForEach for (int i = 0, n = batch.size(); i < n; i++) { Action action = batch.get(i); action.picasso.resumeAction(action); } break; default: throw new AssertionError("Unknown handler message received: " + msg.what); } } };
private void performRemoteViewInto(Request request, RemoteViewsAction action) { if (shouldReadFromMemoryCache(request.memoryPolicy)) { Bitmap bitmap = picasso.quickMemoryCacheCheck(action.request.key); if (bitmap != null) { action.complete(new RequestHandler.Result(bitmap, MEMORY)); return; } } if (placeholderResId != 0) { action.setImageResource(placeholderResId); } picasso.enqueueAndSubmit(action); } }
void resumeAction(Action action) { Bitmap bitmap = null; if (shouldReadFromMemoryCache(action.request.memoryPolicy)) { bitmap = quickMemoryCacheCheck(action.request.key); } if (bitmap != null) { // Resumed action is cached, complete immediately. deliverAction(new RequestHandler.Result(bitmap, MEMORY), action, null); if (loggingEnabled) { log(OWNER_MAIN, VERB_COMPLETED, action.request.logId(), "from " + MEMORY); } } else { // Re-submit the action to the executor. enqueueAndSubmit(action); if (loggingEnabled) { log(OWNER_MAIN, VERB_RESUMED, action.request.logId()); } } }
@Test public void intoNotOnMainThreadCrashes() throws InterruptedException { doCallRealMethod().when(picasso).enqueueAndSubmit(any(Action.class)); final CountDownLatch latch = new CountDownLatch(1); new Thread(new Runnable() { @Override public void run() { try { new RequestCreator(picasso, URI_1, 0).into(mockImageViewTarget()); fail("Should have thrown IllegalStateException"); } catch (IllegalStateException ignored) { } finally { latch.countDown(); } } }).start(); latch.await(); }
@Test public void intoImageViewWithNullUriAndResourceIdSkipsAndCancels() { ImageView target = mockImageViewTarget(); new RequestCreator(picasso, null, 0).into(target); verify(picasso).cancelRequest(target); verify(picasso, never()).quickMemoryCacheCheck(anyString()); verify(picasso, never()).enqueueAndSubmit(any(Action.class)); }
picasso.cancelRequest(target); if (setPlaceholder) { setPlaceholder(target, getPlaceholderDrawable()); setPlaceholder(target, getPlaceholderDrawable()); picasso.defer(target, new DeferredRequestCreator(this, target, callback)); return; Bitmap bitmap = picasso.quickMemoryCacheCheck(request.key); if (bitmap != null) { picasso.cancelRequest(target); RequestHandler.Result result = new RequestHandler.Result(bitmap, MEMORY); setResult(target, picasso.context, result, noFade, picasso.indicatorsEnabled); picasso.enqueueAndSubmit(action);
@Test public void cancelExistingRequestWithTarget() { BitmapTarget target = mockTarget(); Action action = mockAction(URI_KEY_1, URI_1, target); picasso.enqueueAndSubmit(action); assertThat(picasso.targetToAction).hasSize(1); picasso.cancelRequest(target); assertThat(picasso.targetToAction).isEmpty(); verify(action).cancel(); verify(dispatcher).dispatchCancel(action); }
@Test public void intoImageViewSetsPlaceholderDrawable() { PlatformLruCache cache = new PlatformLruCache(0); Picasso picasso = spy(new Picasso(RuntimeEnvironment.application, mock(Dispatcher.class), UNUSED_CALL_FACTORY, null, cache, null, NO_TRANSFORMERS, NO_HANDLERS, mock(Stats.class), ARGB_8888, false, false)); ImageView target = mockImageViewTarget(); Drawable placeHolderDrawable = mock(Drawable.class); new RequestCreator(picasso, URI_1, 0).placeholder(placeHolderDrawable).into(target); verify(target).setImageDrawable(placeHolderDrawable); verify(picasso).enqueueAndSubmit(actionCaptor.capture()); assertThat(actionCaptor.getValue()).isInstanceOf(ImageViewAction.class); }
@Test public void fetchWithMemoryPolicyNoCache() { new RequestCreator(picasso, URI_1, 0).memoryPolicy(MemoryPolicy.NO_CACHE).fetch(); verify(picasso, never()).quickMemoryCacheCheck(URI_KEY_1); verify(picasso).submit(actionCaptor.capture()); }
@Test public void cancelNotOnMainThreadCrashes() throws InterruptedException { doCallRealMethod().when(picasso).cancelRequest(any(BitmapTarget.class)); final CountDownLatch latch = new CountDownLatch(1); new Thread(new Runnable() { @Override public void run() { try { new RequestCreator(picasso, null, 0).into(mockTarget()); fail("Should have thrown IllegalStateException"); } catch (IllegalStateException ignored) { } finally { latch.countDown(); } } }).start(); latch.await(); }
@Before public void setUp() { initMocks(this); picasso = new Picasso(context, dispatcher, UNUSED_CALL_FACTORY, null, cache, listener, NO_TRANSFORMERS, NO_HANDLERS, stats, ARGB_8888, false, false); }
@Test public void intoImageViewWithFitAndNoDimensionsQueuesDeferredImageViewRequest() { ImageView target = mockFitImageViewTarget(true); when(target.getWidth()).thenReturn(0); when(target.getHeight()).thenReturn(0); new RequestCreator(picasso, URI_1, 0).fit().into(target); verify(picasso, never()).enqueueAndSubmit(any(Action.class)); verify(picasso).defer(eq(target), any(DeferredRequestCreator.class)); }
@Test public void preDrawSubmitsRequestAndCleansUp() { Picasso picasso = mock(Picasso.class); when(picasso.transformRequest(any(Request.class))).thenAnswer(TRANSFORM_REQUEST_ANSWER); RequestCreator creator = new RequestCreator(picasso, URI_1, 0); ImageView target = mockFitImageViewTarget(true); when(target.getWidth()).thenReturn(100); when(target.getHeight()).thenReturn(100); ViewTreeObserver observer = target.getViewTreeObserver(); DeferredRequestCreator request = new DeferredRequestCreator(creator, target, null); request.onPreDraw(); verify(observer).removeOnPreDrawListener(request); verify(picasso).enqueueAndSubmit(actionCaptor.capture()); Action value = actionCaptor.getValue(); assertThat(value).isInstanceOf(ImageViewAction.class); assertThat(value.request.targetWidth).isEqualTo(100); assertThat(value.request.targetHeight).isEqualTo(100); } }
/** * Invalidate all memory cached images for the specified {@code path}. You can also pass a * {@linkplain RequestCreator#stableKey stable key}. * * @see #invalidate(Uri) * @see #invalidate(File) */ public void invalidate(@Nullable String path) { if (path != null) { invalidate(Uri.parse(path)); } }
@Test public void completeInvokesErrorOnAllFailedRequests() { Action action1 = mockAction(URI_KEY_1, URI_1, mockImageViewTarget()); Action action2 = mockCanceledAction(); Exception exception = mock(Exception.class); BitmapHunter hunter = mockHunter(URI_KEY_1, null); when(hunter.getException()).thenReturn(exception); when(hunter.getActions()).thenReturn(Arrays.asList(action1, action2)); picasso.complete(hunter); verify(action1).error(exception); verify(action2, never()).error(exception); verify(listener).onImageLoadFailed(picasso, URI_1, exception); }
@Test public void completeWithReplayDoesNotRemove() { Action action = mockAction(URI_KEY_1, URI_1, mockImageViewTarget()); action.willReplay = true; BitmapHunter hunter = mockHunter(URI_KEY_1, new RequestHandler.Result(bitmap, MEMORY)); when(hunter.getAction()).thenReturn(action); picasso.enqueueAndSubmit(action); assertThat(picasso.targetToAction).hasSize(1); picasso.complete(hunter); assertThat(picasso.targetToAction).hasSize(1); verifyActionComplete(action); }
@Test public void throwWhenTransformRequestReturnsNull() { RequestTransformer brokenTransformer = new RequestTransformer() { @Override public Request transformRequest(Request request) { return null; } }; Picasso picasso = new Picasso(context, dispatcher, UNUSED_CALL_FACTORY, null, cache, listener, Collections.singletonList(brokenTransformer), NO_HANDLERS, stats, ARGB_8888, false, false); Request request = new Request.Builder(URI_1).build(); try { picasso.transformRequest(request); fail("Returning null from transformRequest() should throw"); } catch (IllegalStateException expected) { assertThat(expected).hasMessageThat() .isEqualTo("Request transformer " + brokenTransformer.getClass().getCanonicalName() + " returned null for " + request); } }
@Test public void quickMemoryCheckReturnsNullIfNotInCache() { Bitmap cached = picasso.quickMemoryCacheCheck(URI_KEY_1); assertThat(cached).isNull(); verify(stats).dispatchCacheMiss(); }