Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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!

Jake Wharton
PRO

April 13, 2018
Tweet

More Decks by Jake Wharton

Other Decks in Programming

Transcript

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

    View Slide

  2. View Slide

  3. View Slide

  4. View Slide

  5. View Slide

  6. View Slide

  7. 3 years later

    View Slide

  8. 3.x Goals

    View Slide

  9. • Android P
    3.x Goals

    View Slide

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

    View Slide

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

    • Okio integration
    3.x Goals

    View Slide

  12. • Android P
    • OkHttp 2.x => 3.x

    • Okio integration

    • Improvements
    3.x Goals

    View Slide

  13. • Android P
    • OkHttp 2.x => 3.x

    • Okio integration

    • Improvements
    3.x Goals

    View Slide

  14. View Slide

  15. View Slide

  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);
    }

    View Slide

  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);
    }

    View Slide

  18. View Slide

  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);
    }
    }
    });
    }

    View Slide

  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);
    }
    }
    });
    }

    View Slide

  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);
    }
    }
    });
    }

    View Slide

  22. • Android P
    • OkHttp 2.x => 3.x

    • Okio integration

    • Improvements
    3.x Goals

    View Slide

  23. Picasso

    View Slide

  24. Picasso
    ResourceRequestHandler
    AssetsRequestHandler
    NetworkRequestHandler
    FileRequestHandler
    ...

    View Slide

  25. Downloader
    Picasso
    ResourceRequestHandler
    AssetsRequestHandler
    NetworkRequestHandler
    FileRequestHandler
    ...

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  31. Picasso
    OkHttp

    View Slide

  32. Okio
    Picasso
    OkHttp

    View Slide

  33. Picasso
    OkHttp
    Retrofit
    Okio

    View Slide

  34. Picasso
    OkHttp
    Okio
    Retrofit
    Moshi

    View Slide

  35. Picasso
    OkHttp
    Okio
    Retrofit
    Moshi

    View Slide

  36. Picasso
    OkHttp
    Okio
    Retrofit
    Moshi Wire

    View Slide

  37. Picasso
    OkHttp
    Okio
    Retrofit
    Moshi Wire

    View Slide

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

    • Okio integration

    • Improvements
    3.x Goals

    View Slide

  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)

    View Slide

  40. nightmare_shrek.png

    View Slide

  41. MAGIC
    nightmare_shrek.png

    View Slide

  42. METADATA
    METADATA
    METADATA
    MAGIC
    nightmare_shrek.png

    View Slide

  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

    View Slide

  44. PIXEL DATA
    PIXEL DATA
    PIXEL DATA
    PIXEL DATA
    PIXEL DATA
    PIXEL DATA
    PIXEL DATA
    PIXEL DATA
    PIXEL DATA
    METADATA
    METADATA
    METADATA
    MAGIC

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  51. InputStream
    BitmapFactory
    inJustDecodeBounds=true
    MAGIC METADATA

    View Slide

  52. InputStream
    BitmapFactory
    inJustDecodeBounds=true
    MAGIC METADATA

    View Slide

  53. InputStream
    BitmapFactory
    inJustDecodeBounds=true
    MAGIC METADATA
    JPEG?

    View Slide

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

    View Slide

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

    View Slide

  56. InputStream
    BitmapFactory
    inJustDecodeBounds=true
    MAGIC METADATA METADAT

    View Slide

  57. InputStream
    BitmapFactory
    inJustDecodeBounds=true
    MAGIC
    METADATA
    METADAT

    View Slide

  58. InputStream
    BitmapFactory
    inJustDecodeBounds=true
    MAGIC
    METADATA
    METADAT

    View Slide

  59. InputStream
    BitmapFactory
    inJustDecodeBounds=true
    MAGIC METADATA

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  78. InputStream
    BitmapFactory
    inJustDecodeBounds=true
    MAGIC METADATA

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  88. MAGIC METADATA
    METADATA
    METADATA PIXEL DATA
    MarkableInputStream
    MAGIC METADATA
    METADATA
    METADATA PIXEL DATA

    View Slide

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

    View Slide

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

    View Slide

  91. MarkableInputStream
    BitmapFactory
    inJustDecodeBounds=true

    View Slide

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

    View Slide

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

    View Slide

  94. MarkableInputStream
    BitmapFactory
    inJustDecodeBounds=true

    View Slide

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

    View Slide

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

    View Slide

  97. MarkableInputStream
    BitmapFactory
    inJustDecodeBounds=true

    View Slide

  98. MarkableInputStream
    BitmapFactory
    inJustDecodeBounds=true
    PIXEL DATA
    PIXEL DATA

    View Slide

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

    View Slide

  100. MarkableInputStream
    BitmapFactory
    inJustDecodeBounds=true
    PIXEL DATA
    PIXEL DATA

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

  105. BitmapFactory MarkableInputStream InputStream
    BitmapFactory

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  109. BitmapFactory
    inJustDecodeBounds=true
    BufferedSource
    SourceBufferingInputStream

    View Slide

  110. BitmapFactory
    inJustDecodeBounds=true
    BufferedSource
    SourceBufferingInputStream
    offset: 0

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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
    ???

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  141. BitmapFactory InputStream BufferedSource
    BitmapFactory
    inJustDecodeBounds=true
    SourceBufferingInputStream

    View Slide

  142. BitmapFactory
    inJustDecodeBounds=true
    BufferedSource
    SourceBufferingInputStream
    offset: 0

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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°

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  164. • Android P
    • OkHttp 2.x => 3.x

    • Okio integration

    • Improvements
    3.x Goals

    View Slide

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

    View Slide

  166. Picasso

    View Slide

  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)
    }

    View Slide

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

    View Slide

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

    View Slide

  170. View Slide

  171. Picasso
    picasso.load(“http://shrek.jpg”)
    .placeholder(R.drawable.placeholder)
    .error(R.drawable.error)
    .fit()
    .into(view);

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  175. http://shrek.jpg

    View Slide

  176. 0101011010100
    http://shrek.jpg

    View Slide

  177. 0101011010100
    http://shrek.jpg

    View Slide

  178. 01010110101001101

    View Slide

  179. 01010110101001101

    View Slide

  180. 01010110101001101

    View Slide

  181. 01
    01
    0110
    10100
    1 1
    0 1

    View Slide

  182. 01
    01
    0110
    10100
    1 1
    0 1

    View Slide

  183. View Slide

  184. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  188. 0101011

    View Slide

  189. 0101011

    View Slide

  190. 0101011

    View Slide

  191. 0101011

    View Slide

  192. 0101011

    View Slide

  193. 01
    010
    1 1

    View Slide

  194. 01
    010
    1 1

    View Slide

  195. 01
    010
    1 1

    View Slide

  196. View Slide

  197. View Slide

  198. View Slide

  199. ?

    View Slide

  200. View Slide

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

    View Slide

  202. Picasso
    Request Transformer

    View Slide

  203. ResourceRequestHandler
    AssetsRequestHandler
    NetworkRequestHandler
    FileRequestHandler
    Picasso
    Request Transformer

    View Slide

  204. Picasso
    Request Transformer
    Handler
    Request

    View Slide

  205. Picasso
    Request Transformer
    Request Handler
    Bitmap

    View Slide

  206. Bitmap
    Drawable
    Result
    Picasso
    Request Transformer
    Request Handler

    View Slide

  207. Picasso
    Request Transformer
    Result
    Request Handler

    View Slide

  208. Picasso
    Request Transformer
    Result
    Request Handler
    Greyscale
    Circle
    Tint

    View Slide

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

    View Slide

  210. Picasso
    Request Transformer
    Result
    Request Handler
    Transformation

    View Slide

  211. Picasso
    Request Transformer
    Result
    Target
    Request Handler
    Transformation

    View Slide

  212. Request Transformer
    Result
    Request Handler
    Transformation

    View Slide

  213. Transformer
    Result
    Transformer
    Transformer

    View Slide

  214. Transformer
    Transformer
    Transformer

    View Slide

  215. Transformer
    Transformer
    Transformer

    View Slide

  216. Transformer
    Transformer
    Transformer

    View Slide

  217. Transformer
    Transformer
    Transformer

    View Slide

  218. Transformer
    Transformer
    Transformer

    View Slide

  219. View Slide

  220. square/okhttp

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  224. View Slide

  225. View Slide

  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);
    }

    View Slide

  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);
    }

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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()));
    }
    }

    View Slide

  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()));
    }
    }

    View Slide

  234. View Slide

  235. View Slide

  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;
    }
    }

    View Slide

  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;
    }
    }

    View Slide

  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;
    }
    }

    View Slide

  239. public final class PicassoContentProvider extends ContentProvider {
    static Context context;
    @Override public boolean onCreate() {
    context = getContext();
    return true;
    }

    }

    View Slide

  240. View Slide

  241. • Android P
    • OkHttp 2.x => 3.x

    • Okio integration

    • Improvements
    3.x Goals

    View Slide

  242. Picasso.with(context)X
    .load(url)
    .placeholder(R.drawable.placeholder)
    .error(R.drawable.error)
    .fit()
    .into(view);

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  247. Coming Soon

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  251. PICASSO WILL RETURN
    3.0

    View Slide

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

    View Slide