@Test public void doesNotRecycleOriginalTransformationThrows() { Transformation badTransformation = new Transformation() { @Override public Bitmap transform(Bitmap source) { return Bitmap.createBitmap(10, 10, ARGB_8888); } @Override public String key() { return "test"; } }; List<Transformation> transformations = Collections.singletonList(badTransformation); Bitmap original = Bitmap.createBitmap(10, 10, ARGB_8888); try { BitmapHunter.applyCustomTransformations(transformations, original); fail("Expected exception to be thrown."); } catch (RuntimeException e) { assertThat(e).hasMessage("Transformation " + badTransformation.key() + " mutated input Bitmap but failed to recycle the original."); } }
static Bitmap applyCustomTransformations(List<Transformation> transformations, Bitmap result) { for (int i = 0, count = transformations.size(); i < count; i++) { final Transformation transformation = transformations.get(i); Bitmap newResult; try { newResult = transformation.transform(result); } catch (final RuntimeException e) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new RuntimeException( "Transformation " + transformation.key() + " crashed with exception.", e); } }); return null; } if (newResult == null) { final StringBuilder builder = new StringBuilder() .append("Transformation ") .append(transformation.key()) .append(" returned null after ") .append(i) .append(" previous transformation(s).\n\nTransformation list:\n"); for (Transformation t : transformations) { builder.append(t.key()).append('\n'); } Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new NullPointerException(builder.toString()); } }); return null; } if (newResult == result && result.isRecycled()) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new IllegalStateException("Transformation " + transformation.key() + " returned input Bitmap but recycled it."); } }); return null; } if (newResult != result && !result.isRecycled()) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new IllegalStateException("Transformation " + transformation.key() + " mutated input Bitmap but failed to recycle the original."); } }); return null; } result = newResult; } return result; }
BitmapHunter implements Runnable { static Bitmap applyCustomTransformations(List<Transformation> transformations, Bitmap result) { for (int i = 0, count = transformations.size(); i < count; i++) { final Transformation transformation = transformations.get(i); Bitmap newResult; try { newResult = transformation.transform(result); } catch (final RuntimeException e) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new RuntimeException( "Transformation " + transformation.key() + " crashed with exception.", e); } }); return null; } if (newResult == null) { final StringBuilder builder = new StringBuilder() .append("Transformation ") .append(transformation.key()) .append(" returned null after ") .append(i) .append(" previous transformation(s).\n\nTransformation list:\n"); for (Transformation t : transformations) { builder.append(t.key()).append('\n'); } Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new NullPointerException(builder.toString()); } }); return null; } if (newResult == result && result.isRecycled()) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new IllegalStateException("Transformation " + transformation.key() + " returned input Bitmap but recycled it."); } }); return null; } if (newResult != result && !result.isRecycled()) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new IllegalStateException("Transformation " + transformation.key() + " mutated input Bitmap but failed to recycle the original."); } }); return null; } result = newResult; } return result; } }
BitmapHunter implements Runnable { static Bitmap applyCustomTransformations(List<Transformation> transformations, Bitmap result) { for (int i = 0, count = transformations.size(); i < count; i++) { final Transformation transformation = transformations.get(i); Bitmap newResult; try { newResult = transformation.transform(result); } catch (final RuntimeException e) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new RuntimeException( "Transformation " + transformation.key() + " crashed with exception.", e); } }); return null; } if (newResult == null) { final StringBuilder builder = new StringBuilder() .append("Transformation ") .append(transformation.key()) .append(" returned null after ") .append(i) .append(" previous transformation(s).\n\nTransformation list:\n"); for (Transformation t : transformations) { builder.append(t.key()).append('\n'); } Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new NullPointerException(builder.toString()); } }); return null; } if (newResult == result && result.isRecycled()) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new IllegalStateException("Transformation " + transformation.key() + " returned input Bitmap but recycled it."); } }); return null; } if (newResult != result && !result.isRecycled()) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new IllegalStateException("Transformation " + transformation.key() + " mutated input Bitmap but failed to recycle the original."); } }); return null; } result = newResult; } return result; } BitmapHunter(Picasso picasso, Dispatcher dispatcher, Cache cache, Stats stats, Action action,
      RequestHandler requestHandler); }
BitmapHunter implements Runnable { static Bitmap applyCustomTransformations(List<Transformation> transformations, Bitmap result) { for (int i = 0, count = transformations.size(); i < count; i++) { final Transformation transformation = transformations.get(i); Bitmap newResult; try { newResult = transformation.transform(result); } catch (final RuntimeException e) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new RuntimeException( "Transformation " + transformation.key() + " crashed with exception.", e); } }); return null; } if (newResult == null) { final StringBuilder builder = new StringBuilder() .append("Transformation ") .append(transformation.key()) .append(" returned null after ") .append(i) .append(" previous transformation(s).\n\nTransformation list:\n"); for (Transformation t : transformations) { builder.append(t.key()).append('\n'); } Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new NullPointerException(builder.toString()); } }); return null; } if (newResult == result && result.isRecycled()) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new IllegalStateException("Transformation " + transformation.key() + " returned input Bitmap but recycled it."); } }); return null; } if (newResult != result && !result.isRecycled()) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new IllegalStateException("Transformation " + transformation.key() + " mutated input Bitmap but failed to recycle the original."); } }); return null; } result = newResult; } return result; } BitmapHunter(Picasso picasso, Dispatcher dispatcher, Cache cache, Stats stats, Action action,
      RequestHandler requestHandler); @Override void run(); }
BitmapHunter implements Runnable { static Bitmap applyCustomTransformations(List<Transformation> transformations, Bitmap result) { for (int i = 0, count = transformations.size(); i < count; i++) { final Transformation transformation = transformations.get(i); Bitmap newResult; try { newResult = transformation.transform(result); } catch (final RuntimeException e) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new RuntimeException( "Transformation " + transformation.key() + " crashed with exception.", e); } }); return null; } if (newResult == null) { final StringBuilder builder = new StringBuilder() .append("Transformation ") .append(transformation.key()) .append(" returned null after ") .append(i) .append(" previous transformation(s).\n\nTransformation list:\n"); for (Transformation t : transformations) { builder.append(t.key()).append('\n'); } Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new NullPointerException(builder.toString()); } }); return null; } if (newResult == result && result.isRecycled()) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new IllegalStateException("Transformation " + transformation.key() + " returned input Bitmap but recycled it."); } }); return null; } if (newResult != result && !result.isRecycled()) { Picasso.HANDLER.post(new Runnable() { @Override public void run() { throw new IllegalStateException("Transformation " + transformation.key() + " mutated input Bitmap but failed to recycle the original."); } }); return null; } result = newResult; } return result; } BitmapHunter(Picasso picasso, Dispatcher dispatcher, Cache cache, Stats stats, Action action,
      RequestHandler requestHandler); @Override void run();  }