Picasso 2.5.2→2.71828へのマイグレーションについてのメモ

Picasso 2.71828にバージョンアップする際にissueや関連レポジトリを探しまくったので、どんなことがあったのかと思考フローと調べたこと等を雑に記録しておく。

2.5.2での問題

発端は一部の端末でresize()関数を挟むと画像がロードできない問題があった。(必ずonError()関数が呼ばれてしまう。) 手元で再現したのはOS version 6.0.1、Picasso version 2.5.2。

Some images are errored if .resize() applied · Issue #1514 · square/picasso · GitHub

コメントされている解決策が3.0.0-SNAPSHOTにあげることのみだった。

picasso/CHANGELOG.md at master · square/picasso · GitHub

2018/05/01現在version3.0.0はSNAPSHOTなのでその間使うことができる2.71828というバージョンがあるとのことなので、まずは2.71828にあげることにした。

2.5.2→2.71828への変更

2.71828はそれまでの2.x.xのバージョンとは完全に互換性があるわけではないとのこと。主に変更したものは以下。

  • Picasso.with(getContext())メソッドは削除される。Picasso.get()に変更
  • callbackのonError()メソッドの引数にExceptionが渡されるように

picasso2-okhttp3-downloaderとの相性

buildが通るようになってからいくつかの画像が表示されなくなっていることに気づく。 調べるとcallbackが呼ばれていないことに気づく。

setLoggingEnabled(true);

を使ってログを詳細に出す。

Picasso — Cache Indicators, Logging & Stats

このサイトのように正しく表示される画像は以下のようなログに対して、

D/Picasso﹕ Main        created      [R0] Request{http://i.imgur.com/rT5vXE1.jpg}  
D/Picasso﹕ Dispatcher  enqueued     [R0]+21ms  
D/Picasso﹕ Hunter      executing    [R0]+26ms  
D/Picasso﹕ Hunter      decoded      [R0]+575ms  
D/Picasso﹕ Dispatcher  batched      [R0]+576ms for completion  
D/Picasso﹕ Main        completed    [R0]+807ms from NETWORK  
D/Picasso﹕ Dispatcher  delivered    [R0]+809ms  

表示されていないログは

D/Picasso: Main        created      [R2] Request{}
D/Picasso: Dispatcher  enqueued     [R2]+1ms 
D/Picasso: Hunter      executing    [R2]+2ms 

decoded以後のフローが呼ばれていないために画像が表示されていない仮説が立った。

すべての画像が表示されないというわけではなかった。Picassoインスタンスの違いについて調査すると、downloderでOkHttpClientをセットしているインスタンスは画像が表示されていないようだった。

httpリクエストがエラーで返されているかどうかを見るために、OkHttpClientにHttpLoggingInterceptorをセットするなどして追ってみる。 するとそもそもリクエストされていないようだった。(okHttpClientでリクエストする時のnewCall/executeメソッドは共に呼ばれていなかった)

picasso2-okhttp3-downloader側にもissueはあがっているが、組み込んでいてもうこのライブラリは使う必要がなくなるとのこと。

Compatibility with Picasso 2.71828 · Issue #29 · JakeWharton/picasso2-okhttp3-downloader · GitHub

自分は知らなかったが、OkHttp3Downloaderというクラスはpicassoの中にあるものとjakeのpicasso2-okhttp3-downloaderの中にあるものと複数あって、 元々jakeのpicasso2-okhttp3-downloaderのものを使っていたのをpicassoの中にあるOkHttp3Downloaderを使うように変更することで解決された。 (微妙にキャッシュ周りなどの実装が違うのだが、どういう背景で複数できたんだろう…)

ちなみに

Picasso.Builder.downloaderWith(OkHttpClient/Call.Factory)? · Issue #1751 · square/picasso · GitHub

このissueでDownloder経由でOkHttpClientをセットするのを削除しようと議論になっている。

Remove Downloader from API. by NightlyNexus · Pull Request #1787 · square/picasso · GitHub

上のissueから参照されているPRで実際にdownloder()メソッドからclient()メソッドに変更されていることがわかる。

この変更は2.71828に入っていないので3系からなのかな。