Rinsing The Brush: Picasso 3.0 (Chicago Roboto 2018)

Rinsing The Brush: Picasso 3.0 (Chicago Roboto 2018)

Picasso is a powerful image downloading and caching library for Android but since its launch in 2013, other libraries have improved or entered the scene and new requirements have come up.

In this talk, we’ll:

* Dig into the internals of Picasso works
* Compare and contrast to other image libraries
* Discuss latest improvements as we push to 3.0
* …and more!

You’ll learn to efficiently work with different image formats across millions of devices!

Presented with John Rodriguez.

Video: soon!

E68309f117985270285ade8082f4877d?s=128

Jake Wharton

April 13, 2018
Tweet

Transcript

  1. Rinsing the Brush: Picasso 3.0 John Rodriguez Jake Wharton

  2. None
  3. None
  4. None
  5. None
  6. None
  7. 3 years later

  8. 3.x Goals

  9. • Android P 3.x Goals

  10. • Android P • OkHttp 2.x => 3.x 3.x Goals

  11. • Android P • OkHttp 2.x => 3.x
 • Okio

    integration 3.x Goals
  12. • Android P • OkHttp 2.x => 3.x
 • Okio

    integration
 • Improvements 3.x Goals
  13. • Android P • OkHttp 2.x => 3.x
 • Okio

    integration
 • Improvements 3.x Goals
  14. None
  15. None
  16. Bitmap decodeStreamPreP(Request r, BufferedSource bs) { BitmapFactory.Options options = createBitmapOptions(request);

    if (requiresInSampleSize(options)) { InputStream stream = new SourceBufferingInputStream(bs); BitmapFactory.decodeStream(stream, null, options); calculateInSampleSize(r.targetWidth, r.targetHeight, options, r); } return BitmapFactory.decodeStream(bs.inputStream(), null, options); }
  17. Bitmap decodeStreamPreP(Request r, BufferedSource bs) { BitmapFactory.Options options = createBitmapOptions(request);

    if (requiresInSampleSize(options)) { InputStream stream = new SourceBufferingInputStream(bs); BitmapFactory.decodeStream(stream, null, options); calculateInSampleSize(r.targetWidth, r.targetHeight, options, r); } return BitmapFactory.decodeStream(bs.inputStream(), null, options); }
  18. None
  19. Bitmap decodeStreamP(Request r, BufferedSource bs) { ImageDecoder.Source imageSource = ImageDecoder.createSource(ByteBuffer.wrap(bs.readByteArray()));

    return ImageDecoder.decodeBitmap( imageSource, new OnHeaderDecodedListener() { void onHeaderDecoded(ImageDecoder d, ImageInfo info, Source src) { if (r.hasSize()) { d.setTargetSize(r.targetWidth, r.targetHeight); } } }); }
  20. Bitmap decodeStreamP(Request r, BufferedSource bs) { ImageDecoder.Source imageSource = ImageDecoder.createSource(ByteBuffer.wrap(bs.readByteArray()));

    return ImageDecoder.decodeBitmap( imageSource, new OnHeaderDecodedListener() { void onHeaderDecoded(ImageDecoder d, ImageInfo info, Source src) { if (r.hasSize()) { d.setTargetSize(r.targetWidth, r.targetHeight); } } }); }
  21. Bitmap decodeStreamP(Request r, BufferedSource bs) { ImageDecoder.Source imageSource = ImageDecoder.createSource(ByteBuffer.wrap(bs.readByteArray()));

    return ImageDecoder.decodeBitmap( imageSource, new OnHeaderDecodedListener() { void onHeaderDecoded(ImageDecoder d, ImageInfo info, Source src) { if (r.hasSize()) { d.setTargetSize(r.targetWidth, r.targetHeight); } } }); }
  22. • Android P • OkHttp 2.x => 3.x
 • Okio

    integration
 • Improvements 3.x Goals
  23. Picasso

  24. Picasso ResourceRequestHandler AssetsRequestHandler NetworkRequestHandler FileRequestHandler ...

  25. Downloader Picasso ResourceRequestHandler AssetsRequestHandler NetworkRequestHandler FileRequestHandler ...

  26. OkHttp 2.x HttpURLConnection Downloader Picasso ResourceRequestHandler AssetsRequestHandler NetworkRequestHandler FileRequestHandler ...

  27. OkHttp 2.x HttpURLConnection OkHttp 3.x Downloader Picasso ResourceRequestHandler AssetsRequestHandler NetworkRequestHandler

    FileRequestHandler ...
  28. OkHttp 3.x HttpURLConnection OkHttp 2.x Downloader Picasso ResourceRequestHandler AssetsRequestHandler NetworkRequestHandler

    FileRequestHandler ...
  29. OkHttp 3.x Picasso ResourceRequestHandler AssetsRequestHandler NetworkRequestHandler FileRequestHandler ...

  30. Picasso ResourceRequestHandler AssetsRequestHandler NetworkRequestHandler FileRequestHandler ... Call.Factory (OkHttp 3.x)

  31. Picasso OkHttp

  32. Okio Picasso OkHttp

  33. Picasso OkHttp Retrofit Okio

  34. Picasso OkHttp Okio Retrofit Moshi

  35. Picasso OkHttp Okio Retrofit Moshi

  36. Picasso OkHttp Okio Retrofit Moshi Wire

  37. Picasso OkHttp Okio Retrofit Moshi Wire

  38. • Android P • OkHttp 2.x => 3.x
 • Okio

    integration
 • Improvements 3.x Goals
  39. java.io.IOException: Cannot reset at com.squareup.picasso.MarkableInputStream.reset(MarkableInputStream.java:99) at com.squareup.picasso.BitmapHunter.decodeStream(BitmapHunter.java:140) at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:217) at

    com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:159) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:411)
  40. nightmare_shrek.png

  41. MAGIC nightmare_shrek.png

  42. METADATA METADATA METADATA MAGIC nightmare_shrek.png

  43. PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA

    PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA METADATA METADATA METADATA MAGIC nightmare_shrek.png
  44. PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA

    PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA METADATA METADATA METADATA MAGIC
  45. PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA

    PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA METADATA METADATA METADATA MAGIC
  46. PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA

    PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA METADATA METADATA METADATA MAGIC
  47. PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA

    PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA METADATA METADATA METADATA MAGIC
  48. PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA

    PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA METADATA METADATA METADATA MAGIC
  49. PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA

    PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA METADATA METADATA METADATA MAGIC
  50. InputStream PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA PIXEL

    DATA PIXEL DATA PIXEL DATA PIXEL DATA PIXEL DATA METADATA METADATA METADATA MAGIC
  51. InputStream BitmapFactory inJustDecodeBounds=true MAGIC METADATA

  52. InputStream BitmapFactory inJustDecodeBounds=true MAGIC METADATA

  53. InputStream BitmapFactory inJustDecodeBounds=true MAGIC METADATA JPEG?

  54. InputStream BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADAT JPEG?

  55. InputStream BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADAT JPEG?

  56. InputStream BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADAT

  57. InputStream BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADAT

  58. InputStream BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADAT

  59. InputStream BitmapFactory inJustDecodeBounds=true MAGIC METADATA

  60. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA

  61. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA JPEG?

  62. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA JPEG?

  63. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA JPEG?

  64. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA

  65. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA PNG?

  66. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA PNG?

  67. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA PNG!

  68. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA PNG

  69. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA PNG size?

  70. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA PNG size?

  71. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA PNG 1920x1080!

  72. BitmapFactory inJustDecodeBounds=true MAGIC METADATA 2METADATA2 1METADATA1 PIXEL DATA PNG 1920x1080

  73. BitmapFactory inJustDecodeBounds=true MAGIC METADATA 2METADATA2 1METADATA1 PIXEL DATA 1920x1080

  74. InputStream BitmapFactory BitmapFactory inJustDecodeBounds=true MAGIC METADATA 2METADATA2 1METADATA1 PIXEL DATA

    1920x1080 PIXEL DAT
  75. InputStream BitmapFactory inJustDecodeBounds=true BitmapFactory PIXEL DATA MAGIC METADATA 2METADATA2 1METADATA1

    PIXEL DATA 1920x1080
  76. InputStream BitmapFactory inJustDecodeBounds=true BitmapFactory PIXEL DATA MAGIC METADATA 2METADATA2 1METADATA1

    PIXEL DATA 1920x1080
  77. InputStream BitmapFactory inJustDecodeBounds=true BitmapFactory PIXEL DATA MAGIC METADATA 2METADATA2 1METADATA1

    PIXEL DATA 1920x1080
  78. InputStream BitmapFactory inJustDecodeBounds=true MAGIC METADATA

  79. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA MarkableInputStream

  80. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA MarkableInputStream MAGIC

    METADATA METADATA METADATA PIXEL DATA
  81. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA MarkableInputStream MAGIC

    METADATA METADATA METADATA PIXEL DATA 1920x1080
  82. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA MarkableInputStream MAGIC

    METADATA METADATA METADATA PIXEL DATA 1920x1080
  83. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA MarkableInputStream MAGIC

    METADATA METADATA METADATA PIXEL DATA 1920x1080 BitmapFactory MAGIC METADATA METADATA METADATA PIXEL DATA
  84. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA MarkableInputStream MAGIC

    METADATA METADATA METADATA PIXEL DATA 1920x1080 MAGIC METADATA METADATA METADATA PIXEL DATA BitmapFactory
  85. BitmapFactory inJustDecodeBounds=true MarkableInputStream MAGIC METADATA METADATA METADATA PIXEL DATA 1920x1080

    BitmapFactory
  86. PIXEL DATA PIXEL DATA PIXEL DATA BitmapFactory inJustDecodeBounds=true MarkableInputStream MAGIC

    METADATA METADATA METADATA PIXEL DATA 1920x1080 BitmapFactory
  87. PIXEL DATA PIXEL DATA PIXEL DATA BitmapFactory inJustDecodeBounds=true MarkableInputStream MAGIC

    METADATA METADATA METADATA PIXEL DATA 1920x1080 BitmapFactory PIXEL DATA PIXEL DATA PIXEL DATA
  88. MAGIC METADATA METADATA METADATA PIXEL DATA MarkableInputStream MAGIC METADATA METADATA

    METADATA PIXEL DATA
  89. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA MarkableInputStream MAGIC

    METADATA METADATA METADATA PIXEL DATA
  90. BitmapFactory inJustDecodeBounds=true MAGIC METADATA METADATA METADATA PIXEL DATA MarkableInputStream MAGIC

    METADATA METADATA METADATA PIXEL DATA
  91. MarkableInputStream BitmapFactory inJustDecodeBounds=true

  92. PIXEL DATA PIXEL DATA PIXEL DATA MarkableInputStream BitmapFactory inJustDecodeBounds=true

  93. PIXEL DATA PIXEL DATA PIXEL DATA MarkableInputStream BitmapFactory inJustDecodeBounds=true PIXEL

    DATA PIXEL DATA PIXEL DATA
  94. MarkableInputStream BitmapFactory inJustDecodeBounds=true

  95. MarkableInputStream BitmapFactory inJustDecodeBounds=true PIXEL DATA PIXEL DATA PIXEL DATA

  96. MarkableInputStream BitmapFactory inJustDecodeBounds=true PIXEL DATA PIXEL DATA PIXEL DATA PIXEL

    DATA PIXEL DATA PIXEL DATA
  97. MarkableInputStream BitmapFactory inJustDecodeBounds=true

  98. MarkableInputStream BitmapFactory inJustDecodeBounds=true PIXEL DATA PIXEL DATA

  99. MarkableInputStream BitmapFactory inJustDecodeBounds=true PIXEL DATA PIXEL DATA PIXEL DATA PIXEL

    DATA
  100. MarkableInputStream BitmapFactory inJustDecodeBounds=true PIXEL DATA PIXEL DATA

  101. MarkableInputStream BitmapFactory inJustDecodeBounds=true ??? PIXEL DATA PIXEL DATA

  102. MarkableInputStream BitmapFactory inJustDecodeBounds=true ??? PIXEL DATA PIXEL DATA

  103. MarkableInputStream BitmapFactory inJustDecodeBounds=true ??? BitmapFactory PIXEL DATA PIXEL DATA

  104. MarkableInputStream BitmapFactory inJustDecodeBounds=true ??? BitmapFactory java.io.IOException: Cannot reset at com.squareup.picasso.MarkableInputStream.reset(MarkableInputStream.java:99)

    at com.squareup.picasso.BitmapHunter.decodeStream(BitmapHunter.java:140) at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:217) at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:159) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:411)
  105. BitmapFactory MarkableInputStream InputStream BitmapFactory

  106. BitmapFactory MarkableInputStream InputStream Picasso 2.x BitmapFactory Picasso 3.x

  107. BitmapFactory MarkableInputStream InputStream Picasso 2.x BitmapFactory BufferedSource Picasso 3.x

  108. BitmapFactory MarkableInputStream InputStream Picasso 2.x BitmapFactory BufferedSource Picasso 3.x SourceBufferingInputStream

  109. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream

  110. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream offset: 0

  111. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC

    offset: 0
  112. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC

    offset: 0 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC 1024
  113. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC

    offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC 0
  114. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC

    offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC
  115. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC

    offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC
  116. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC

    offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC
  117. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC

    offset: 1024
  118. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 1024
  119. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 1024 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4 2048
  120. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 2048 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4 1024
  121. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 2048 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4
  122. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 2048
  123. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 2048
  124. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 2048 5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 3072
  125. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 3072 5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 2048
  126. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 3072 5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7
  127. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 3072
  128. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 3072
  129. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset:x3072 8PIXEL DATA8 9PIXEL DATA9 3754
  130. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 3754 8PIXEL DATA8 9PIXEL DATA9 x3072
  131. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 3754 8PIXEL DATA8 9PIXEL DATA9
  132. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 3754
  133. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4

    5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 3754 ???
  134. BufferedSource 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4 5PIXEL DATA5 6PIXEL

    DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC offset: 3754 ??? BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream
  135. BitmapFactory InputStream BufferedSource 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4 5PIXEL

    DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream
  136. BitmapFactory InputStream BufferedSource 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4 5PIXEL

    DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream
  137. BitmapFactory InputStream BufferedSource 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4 5PIXEL

    DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream
  138. BitmapFactory InputStream BufferedSource 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4 5PIXEL

    DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream
  139. BitmapFactory InputStream BufferedSource 5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL

    DATA8 9PIXEL DATA9 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream
  140. BitmapFactory InputStream BufferedSource 8PIXEL DATA8 9PIXEL DATA9 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream

  141. BitmapFactory InputStream BufferedSource BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream

  142. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream offset: 0

  143. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1METADATA1 MAGIC offset: 0

  144. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1METADATA1 MAGIC offset: 341 1METADATA1 MAGIC

  145. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1METADATA1 MAGIC offset: 341 1METADATA1 MAGIC

  146. BitmapFactory inJustDecodeBounds=true BufferedSource SourceBufferingInputStream 1METADATA1 MAGIC offset: 341 1METADATA1 MAGIC

    1920x1080
  147. BufferedSource 1METADATA1 MAGIC 1METADATA1 MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream

    1920x1080
  148. ExifInterface BufferedSource SourceBufferingInputStream 1METADATA1 MAGIC 1METADATA1 MAGIC offset: 341 BitmapFactory

    inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 0
  149. ExifInterface BufferedSource SourceBufferingInputStream 1METADATA1 MAGIC 1METADATA1 MAGIC offset: 341 BitmapFactory

    inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 341 1METADATA1 MAGIC
  150. ExifInterface BufferedSource SourceBufferingInputStream 1METADATA1 MAGIC 1METADATA1 MAGIC offset: 341 BitmapFactory

    inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 341 1METADATA1 MAGIC
  151. ExifInterface BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC 1METADATA1

    MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 341
  152. ExifInterface BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC 1METADATA1

    MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341
  153. ExifInterface BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC 1METADATA1

    MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341
  154. ExifInterface BufferedSource SourceBufferingInputStream 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC 1METADATA1

    MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341 90°
  155. BufferedSource 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC 1METADATA1 MAGIC offset:

    341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341 90° ExifInterface SourceBufferingInputStream
  156. BitmapFactory InputStream BufferedSource 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC 1METADATA1

    MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341 90° ExifInterface SourceBufferingInputStream
  157. BitmapFactory InputStream BufferedSource 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4 1PIXEL

    DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC 1METADATA1 MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341 90° ExifInterface SourceBufferingInputStream
  158. BitmapFactory InputStream BufferedSource 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4 5PIXEL

    DATA5 6PIXEL DATA6 7PIXEL DATA7 1PIXEL DATA1 3METADATA3 2METADATA2 1METADATA1 MAGIC 1METADATA1 MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341 90° ExifInterface SourceBufferingInputStream
  159. BitmapFactory InputStream BufferedSource 2PIXEL DATA2 3PIXEL DATA3 4PIXEL DATA4 5PIXEL

    DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL DATA8 9PIXEL DATA9 1METADATA1 MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341 90° ExifInterface SourceBufferingInputStream
  160. BitmapFactory InputStream BufferedSource 5PIXEL DATA5 6PIXEL DATA6 7PIXEL DATA7 8PIXEL

    DATA8 9PIXEL DATA9 1METADATA1 MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341 90° ExifInterface SourceBufferingInputStream
  161. BitmapFactory InputStream BufferedSource 8PIXEL DATA8 9PIXEL DATA9 1METADATA1 MAGIC offset:

    341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream 1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341 90° ExifInterface SourceBufferingInputStream
  162. BitmapFactory InputStream BufferedSource 1METADATA1 MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream

    1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341 90° ExifInterface SourceBufferingInputStream
  163. BitmapFactory InputStream BufferedSource 1METADATA1 MAGIC offset: 341 BitmapFactory inJustDecodeBounds=true SourceBufferingInputStream

    1920x1080 offset: 1024 1PIXEL DATA1 3METADATA3 2METADATA2 341 90° ExifInterface SourceBufferingInputStream
  164. • Android P • OkHttp 2.x => 3.x
 • Okio

    integration
 • Improvements 3.x Goals
  165. Picasso picasso.load(url) .placeholder(R.drawable.placeholder) .error(R.drawable.error) .fit() .into(view);

  166. Picasso

  167. Picasso fun loadImage( remoteUri: Uri, @ColorInt tintColor: Int? = null

    ) { val creator = picasso.load(remoteUri) .placeholder(avatarPlaceholder) .fit() if (transformTintColor != null) { creator.transform(TintTransformation(tintColor)) } creator.into(this) }
  168. Picasso fun loadImage( awsAssetUri: Uri, height: Int, width: Int )

    { val creator = picasso.load(awsAssetUri) .placeholder(avatarPlaceholder) .fit() .into(this) }
  169. Picasso fun loadImage( awsAssetUri: Uri, height: Int, width: Int )

    { val creator = picasso.load(awsAssetUri) .placeholder(avatarPlaceholder) .fit() .into(this) }
  170. None
  171. Picasso picasso.load(“http://shrek.jpg”) .placeholder(R.drawable.placeholder) .error(R.drawable.error) .fit() .into(view);

  172. Picasso Request “http://shrek.jpg”

  173. Picasso Request Request Transformer Request “http://shrek.jpg”

  174. Picasso Request “http://shrek.jpg” Request Transformer Request “http://bar.com/20x20/shrek.jpg”

  175. http://shrek.jpg

  176. 0101011010100 http://shrek.jpg

  177. 0101011010100 http://shrek.jpg

  178. 01010110101001101

  179. 01010110101001101

  180. 01010110101001101

  181. 01 01 0110 10100 1 1 0 1

  182. 01 01 0110 10100 1 1 0 1

  183. None
  184. None
  185. http://bar.com/20x20/shrek.jpg

  186. http://bar.com/20x20/shrek.jpg

  187. http://bar.com/20x20/shrek.jpg

  188. 0101011

  189. 0101011

  190. 0101011

  191. 0101011

  192. 0101011

  193. 01 010 1 1

  194. 01 010 1 1

  195. 01 010 1 1

  196. None
  197. None
  198. None
  199. ?

  200. None
  201. Picasso Request “http://shrek.jpg” Request Transformer Request’ “http://bar.com/20x20/shrek.jpg”

  202. Picasso Request Transformer

  203. ResourceRequestHandler AssetsRequestHandler NetworkRequestHandler FileRequestHandler Picasso Request Transformer

  204. Picasso Request Transformer Handler Request

  205. Picasso Request Transformer Request Handler Bitmap

  206. Bitmap Drawable Result Picasso Request Transformer Request Handler

  207. Picasso Request Transformer Result Request Handler

  208. Picasso Request Transformer Result Request Handler Greyscale Circle Tint

  209. Greyscale Circle Tint Picasso Request Transformer Result Request Handler Transformation

  210. Picasso Request Transformer Result Request Handler Transformation

  211. Picasso Request Transformer Result Target Request Handler Transformation

  212. Request Transformer Result Request Handler Transformation

  213. Transformer Result Transformer Transformer

  214. Transformer Transformer Transformer

  215. Transformer Transformer Transformer

  216. Transformer Transformer Transformer

  217. Transformer Transformer Transformer

  218. Transformer Transformer Transformer

  219. None
  220. square/okhttp

  221. custom interceptors Retry Bridge Cache Connect Call Server square/okhttp

  222. custom interceptors Retry Bridge Cache Connect Call Server square/okhttp

  223. custom interceptors Retry Bridge Cache Connect Call Server square/okhttp

  224. None
  225. None
  226. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Picasso.with(this) .load("http://example.com/logo.png")

    .into(imageView); }
  227. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Picasso.with(this) .load("http://example.com/logo.png")

    .into(imageView); }
  228. public static Picasso with(Context context) { if (singleton == null)

    { synchronized (Picasso.class) { if (singleton == null) { singleton = new Builder(context).build(); } } } return singleton; }
  229. public static Picasso with(Context context) { if (singleton == null)

    { synchronized (Picasso.class) { if (singleton == null) { singleton = new Builder(context).build(); } } } return singleton; }
  230. public static void setSingletonInstance(Picasso picasso) { synchronized (Picasso.class) { if

    (singleton != null) { throw new IllegalStateException( "Singleton instance already exists."); } singleton = picasso; } }
  231. public static void setSingletonInstance(Picasso picasso) { synchronized (Picasso.class) { if

    (singleton != null) { throw new IllegalStateException( "Singleton instance already exists."); } singleton = picasso; } }
  232. @Module(includes = ThumborModule.class) final class ProductionPicassoModule { @Provides @Singleton static

    Picasso providePicasso( @App Context context, OkHttpClient client, Thumbor thumbor) { Picasso.RequestTransformer transformer = new PollexorRequestTransformer(thumbor); return new Picasso.Builder(context) .client(client) .requestTransformer(transformer) .listener((picasso, uri, e) -> Timber.d(e, uri.toString())); } }
  233. @Module(includes = ThumborModule.class) final class ProductionPicassoModule { @Provides @Singleton static

    Picasso providePicasso( @App Context context, OkHttpClient client, Thumbor thumbor) { Picasso.RequestTransformer transformer = new PollexorRequestTransformer(thumbor); return new Picasso.Builder(context) .client(client) .requestTransformer(transformer) .listener((picasso, uri, e) -> Timber.d(e, uri.toString())); } }
  234. None
  235. None
  236. public final class PicassoProvider { private static volatile Picasso instance;

    public static Picasso get() { if (instance == null) { synchronized (PicassoProvider.class) { if (instance == null) { if (PicassoContentProvider.context == null) { throw new IllegalStateException("context == null"); } instance = new Picasso.Builder(PicassoContentProvider.context).build(); } } } return instance; } }
  237. public final class PicassoProvider { private static volatile Picasso instance;

    public static Picasso get() { if (instance == null) { synchronized (PicassoProvider.class) { if (instance == null) { if (PicassoContentProvider.context == null) { throw new IllegalStateException("context == null"); } instance = new Picasso.Builder(PicassoContentProvider.context).build(); } } } return instance; } }
  238. public final class PicassoProvider { private static volatile Picasso instance;

    public static Picasso get() { if (instance == null) { synchronized (PicassoProvider.class) { if (instance == null) { if (PicassoContentProvider.context == null) { throw new IllegalStateException("context == null"); } instance = new Picasso.Builder(PicassoContentProvider.context).build(); } } } return instance; } }
  239. public final class PicassoContentProvider extends ContentProvider { static Context context;

    @Override public boolean onCreate() { context = getContext(); return true; } … }
  240. None
  241. • Android P • OkHttp 2.x => 3.x
 • Okio

    integration
 • Improvements 3.x Goals
  242. Picasso.with(context)X .load(url) .placeholder(R.drawable.placeholder) .error(R.drawable.error) .fit() .into(view);

  243. PicassoProvider.get()X .load(url) .placeholder(R.drawable.placeholder) .error(R.drawable.error) .fit() .into(view); with context

  244. picasso.load(url) .placeholder(R.drawable.placeholder) .error(R.drawable.error) .fit() .into(view);

  245. abstract class RequestHandler { abstract boolean canHandleRequest(Request request); abstract Result

    load(Request request, int networkPolicy); }X
  246. abstract class RequestHandler { abstract boolean canHandleRequest(Request request); abstract void

    load(Picasso picasso, Request request, Callback callback); }X Result int networkPolicy
  247. Coming Soon

  248. • Better separation of concerns: Source/Target/Load Coming Soon

  249. • Better separation of concerns: Source/Target/Load • Propagating Drawables to

    Target (animated GIFs!) Coming Soon
  250. • Better separation of concerns: Source/Target/Load • Propagating Drawables to

    Target (animated GIFs!) • More? Let us know! Coming Soon
  251. PICASSO WILL RETURN 3.0

  252. Rinsing the Brush: Picasso 3.0 @jrodbx @JakeWharton