Unyablog.

のにれんのブログ

Android Studio をビルドする

この記事は KMC アドベントカレンダー 4日目の記事です。自分は5日目だと思っていてのんびりしてました… :bow: :bow:

www.adventar.org

昨日は id:nojima718 さんの

nojima.hatenablog.com

でした!

本題

今回は Android Studio をビルドしてみます。

大体ここに従ってます。

tools.android.com

何故

Android Studio 2.2 になってから mac で外部ディスプレイに繋げたときに色が全体的に色が濃くなりました。僕の使ってる Molokai テーマには致命的で、元からコントラストが高いのにさらに濃くなると目が痛くて仕方ありません。

だからといってテーマ変えても濃くてつらく、最近は外部ディスプレイに繋がずに使っていました。

ここで Android Studio の更新ログを見ると

Improved color management on OS X

とのこと。

もしこれのせいなら、 該当する Commit を Revert して自分でビルドすればいいのでは? と思い立ち、とりあえず自分でビルドしてみることにしました。

ちなみに原因はそれではありませんでした(後述)。

ビルド

ソースコード

repo

Android では複数の git repository を一度に扱う repo というコマンドで管理することを推奨しています。*1

Repo command reference | Android Open Source Project

上に従って repo (実体は Python スクリプト) をダウンロードして実行できるようにします。

repo sync

次は適当な場所にソースコードをダウンロードします。とりあえずビルドしてみるだけなので --depth=1 としてファイル容量を抑えています。*2

$ mkdir studio
$ cd studio
$ repo init -u https://android.googlesource.com/platform/manifest -b studio-2.2.2 --depth=1
$ repo sync

大量のレポジトリが 3GB ほど降ってきます。後のビルドでも 5GB 程度は容量食うのでそれなりに確保しておきましょう。

ビルド

とりあえずビルドしてみます。ドキュメントにある通り、 ant をインストールした後

$ cd tools/idea
$ ant

とすれば後はビルド終了を待つのみ。

自分の Macbook では 20 分ほどかかりました。ポケモンピクロスでもして待っていましょう。

成果物

tools/idea/out/artifacts 以下にビルドした AndroidStudio 達が存在しています。Mac でビルドしましたが Windows / X Window 用も作られていました。

$ ls out/artifacts
android-studio-SNAPSHOT-no-jdk.mac.zip
android-studio-SNAPSHOT-no-jdk.tar.gz
android-studio-SNAPSHOT-no-jdk.win.zip
core
intellij-core-AI-145.SNAPSHOT.zip
jps
sources.zip

ここから android-studio-SNAPSHOT-no-jdk.mac.zip を解凍すれば Android Studio.app が生成されます。こうして自分専用の Android Studio が使えるようになりました。

JDK

ところでファイル名を見ると no-jdk となっており、Idea JDK が含まれていないようです。なくても困ることはないですが、推奨されているのだから使いたい。

どうやら prebuilts/studio/jdk に然るべき JDK を置けば一緒に含めてくれるみたいです。

ということで、repo のレポジトリ管理ファイルである manifest.xml に新しいレポジトリを追加します。

ローカルの manifest.repo/local_manifests に置けば良いので、.repo/local_manifests/manifest.xml

<?xml version="1.0" encoding="UTF-8"?>
<manifest>

  <remote  name="aosp"
           fetch=".."
           review="https://android-review.googlesource.com/" />

  <project path="prebuilts/studio/jdk" name="platform/prebuilts/studio/jdk" clone-depth="1" revision="studio-master-dev"/>

</manifest>

と記述して repo sync します。

すると prebuilts/studio/jdkplatform/prebuilts/studio/jdk (https://android.googlesource.com/platform/prebuilts/studio/jdk/) の studio-master-dev ブランチが clone されるので、再ビルドすると

$ ls out/artifacts
android-studio-SNAPSHOT-no-jdk.mac.zip
android-studio-SNAPSHOT-no-jdk.tar.gz
android-studio-SNAPSHOT-no-jdk.win.zip
android-studio-SNAPSHOT.mac.zip
android-studio-SNAPSHOT.tar.gz
android-studio-SNAPSHOT.win.zip
android-studio-SNAPSHOT.win32.zip
core
intellij-core-AI-145.SNAPSHOT.zip
jps
sources.zip

が生成されました。

しかし、実行してみると起動してくれない…。ブランチが違ったりしてるし諦めて JDK 無しでやりました。

その後

実行できたので早速 git のログを漁り初めたのですが、それっぽいログがない。実際にソースを見てみてもそれっぽい部分がないので困っていると、ちょうどそれらしきプラグインを発見。*3

github.com

どうやら問題は IntelliJJDK を Idea JDK (8) に切り替えたことが原因のようです。

https://youtrack.jetbrains.com/issue/IDEA-149601

...ということでプラグインを入れることで問題が解決してしまった?。*4

ビルドが終わった頃には studio ディレクトリは 12GB も食っていました。残り容量はなんと 500MB になり、警告も出ています。

よって、速やかに studio を削除してこの話は終わりとします。ありがとうございました。

$ df -h 
Filesystem      Size  Used Avail Use% Mounted on
/dev/disk1      186G  185G  529M 100% /
/dev/disk0s4     47G   27G   21G  57% /Volumes/BOOTCAMP
$ rm -rf studio
rm -rf studio  0.81s user 20.83s system 60% cpu 35.700 total
$  df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/disk1      186G  173G   13G  94% /
/dev/disk0s4     47G   27G   21G  57% /Volumes/BOOTCAMP

余談

  • Cross Compile...?

Windows 用はどうやって作っているのだろうと見たところ、ある程度の exe は初めから置いておいて、最後は気合の実装で作るという感じでした。すごい。他のプラットフォームも割りとそういう感じ。

intellij-community/tools/launcher-generator/src/com/pme/exe at master · JetBrains/intellij-community · GitHub

ということは何か将来個人的な変更を加えたい場合は、 CI に投げて自動的に MacWindows 用の AndroidStudio を作るといったことができそう。

  • 容量問題

ソースコードを見たいだけなら https://android.googlesource.com/platform/ から見たいものを clone するだけで良いです。ビルドにはいろいろ必要ですが、見るべきなのは一つのリポジトリ程度なので。

また、intellij 本家を GitHub で見るのもオススメです。

github.com

明日

明日(今日)は id:tyage さんです!!!楽しみですね!!!

*1:使わなければ一つ一つレポジトリを clone していくことになりめんどくさい

*2:depth を付けないと 8GB ほど埋まるので注意

*3:偶然にもこの方の IntelliJ 用 Molokai テーマを弄ったものを使っていた

*4:まだ試してませんが

curl: (60) SSL certificate problem: certificate is not yet valid

対処

時刻がおかしいので ntp とか入れる

経緯とか

久しぶりに VirtualBox で入れていた Arch Linux を起動して、 bundler が入っていなかったので gem install bundler を打つと、

certificate verify failed

とのエラーが *1

確かに curl https://rubygems.org しても上手くいかないし、 curl http://google.com も無理。でも github は上手くいくから何故だろうと思っていた。

$ curl https://google.com
curl: (60) SSL certificate problem: certificate is not yet valid

と言った感じ。(ここでちゃんとログを見ればすぐ解決してた...)

ルート証明書が古かったりおかしかったりするのかなと思ったけど /etc/ssl にちゃんとあるし、変ですねと思ってもう一回ログを見たら "not yet valid" って言ってる。

もしかして時間・・・?と思って date したら内部の日付が一ヶ月半前だった。そりゃダメだ。

Arch, デフォルトでは ntp で同期してないんですね。

結局

# pacman -S ntp
# systemctl enable ntpd.service
# systemctl start ntpd.service

したら直った。

追記

Systemd にそもそも組み込まれていたのでそっちを ON にすればいいという指摘をもらった。ということでそっちを使うように。

# pacman -R ntp
# timedatectl set-ntp false
# timedatectl set-ntp true

一度 false にしないと、 NTP synchronizedno のままだった。

*1:詳しいログまでは記憶してない

Android の df コマンドについて

最近 Android 用の mackerel-agent を作ろうとしていて、Android/proc/meminfo を読んだりしていたのですが、 filesystem の metrics は df -P コマンドを使っていました。*1

Android にも df コマンドは存在していたのでパースしようとしたのですが、バージョンごとの違いなどがあったのでメモ。

バージョンによる挙動

Andorid 6.0.1 (Marshmallow) まで

$ adb shell
shell@SO-02H:/ $ df
Filesystem               Size     Used     Free   Blksize
/dev                   889.4M   104.0K   889.3M   4096
/sys/fs/cgroup         889.4M     0.0K   889.4M   4096
/sys/fs/cgroup/memory: Permission denied
/mnt                   889.4M     0.0K   889.4M   4096
/tmp                   889.4M     4.0K   889.4M   4096
/system                  4.9G     3.9G     1.1G   4096
/data                   21.9G    12.1G     9.8G   4096
/oem                   503.7M   340.1M   163.6M   4096
/cache                 341.0M   304.0K   340.7M   4096
/rca                     8.4M     6.4M     1.9M   1024
/idd                    14.0M     4.9M     9.0M   1024
/persist                27.5M   804.0K    26.7M   4096
/firmware               80.0M    56.5M    23.5M   16384
/lta-label              11.7M     1.1M    10.6M   4096
/storage               889.4M     0.0K   889.4M   4096
/mnt/runtime/default/emulated: Permission denied
/storage/emulated       21.9G    12.1G     9.8G   4096
/mnt/runtime/read/emulated: Permission denied
/mnt/runtime/write/emulated: Permission denied

Android 6.0 までの df コマンドは coreutilsdf とは大きく異なります。

マウントされた先しか見ることが出来ない他、 -h などのオプションは一切使えません。

$ adb shell
shell@SO-02H:/ $ df -h
Filesystem               Size     Used     Free   Blksize
-h: No such file or directory

Android 7.0 (Nougat) 以降? *2

$ adb shell
bullhead:/ $ df
Filesystem                                             1K-blocks     Used Available Use% Mounted on
tmpfs                                                     922680      428    922252   1% /dev
tmpfs                                                     922680        0    922680   0% /mnt
/dev/block/dm-0                                          2999516  2430552    552580  82% /system
/dev/block/dm-1                                           241908   184160     52752  78% /vendor
/dev/block/platform/soc.0/f9824900.sdhci/by-name/cache     92656     4504     86188   5% /cache
/dev/block/platform/soc.0/f9824900.sdhci/by-name/modem     88016    56720     31296  65% /firmware
/dev/block/dm-2                                         26094648 12222956  13855308  47% /data
/dev/fuse                                               26094648 12222956  13855308  47% /storage/emulated

Android 7.0 では coreutils と同じ形式になりました。

-h-P などのオプションも使えるようになり便利。

$ adb shell
bullhead:/ $ df -h
Filesystem                                             Size  Used Avail Use% Mounted on
tmpfs                                                  901M  428K  901M   1% /dev
tmpfs                                                  901M     0  901M   0% /mnt
/dev/block/dm-0                                        2.8G  2.3G  540M  82% /system
/dev/block/dm-1                                        236M  180M   52M  78% /vendor
/dev/block/platform/soc.0/f9824900.sdhci/by-name/cache  90M  4.3M   84M   5% /cache
/dev/block/platform/soc.0/f9824900.sdhci/by-name/modem  86M   55M   31M  65% /firmware
tmpfs                                                  901M     0  901M   0% /storage
/dev/block/dm-2                                         25G   12G   13G  47% /data
/dev/fuse                                               25G   12G   13G  47% /storage/emulated

細かい話

  • Android 6.0 までの実装は以下にあり、Android toolbox に含まれていました。/proc/mounts から読み取っていますが特にオプションを受け取るなどは行っていません。

platform_system_core/df.c at marshmallow-release · android/platform_system_core · GitHub

  • Android 7.0 からは df の実装が toybox に置き換わったので、POSIX に準拠するようになりました。

Lose df to toybox. · android/platform_system_core@cca6019 · GitHub

toybox とは linux コマンド群の BSD ライセンス実装です*3

おまけ

toybox 自体は 6.0 から Android に取り込まれているので、toybox を使えば 6.0 でも新しい df を使えました。

$ adb shell
shell@SO-02H:/ $ toybox df
Filesystem      1K-blocks       Used  Available Use% Mounted on
tmpfs              910748        104     910644   1% /dev
none               910748          0     910748   0% /sys/fs/cgroup
tmpfs              910748          0     910748   0% /mnt
tmpfs              910748          4     910744   1% /tmp
/dev/block/dm-0   5174428    4054116    1103928  79% /system
/dev/block/bootdevice/by-name/userdata 22994780   12698312   10280084  56% /data
/dev/block/bootdevice/by-name/oem 515776     348284     156844  69% /oem
/dev/block/bootdevice/by-name/cache 349136        304     341624   1% /cache
/dev/block/bootdevice/by-name/diag 14327       5165       8835  37% /idd
/dev/block/bootdevice/by-name/persist 28144        804      26688   3% /persist
/dev/block/bootdevice/by-name/modem 81872      57824      24048  71% /firmware
/dev/block/bootdevice/by-name/LTALabel 12016       1168      10524  10% /lta-label
/dev/fuse        22994780   12698312   10280084  56% /storage/emulated

ただ、toybox のバージョンが少し古いので長い filesystem に対応できずはみ出しています。*4

ということで、今回は Android 6.0 以前と Android 7.0 以降でパースを分けるという対応になりそうです。toybox のおかげで色々コマンド打てるようになって便利。

*1:https://github.com/mackerelio/mackerel-agent/blob/master/util/filesystem.go

*2:未来のことはわからない

*3:busybox は GPL2 なので Android のライセンス上含められなかったそう

*4:ここで修正されている https://github.com/landley/toybox/commit/c10638d3b16d065c1efd97ae17c1a8bf417be706

cookpad のインターンに行ってきた話

8/10 から今日まで一ヶ月間、恵比寿にあるクックパッドインターンに行っていました。忘れないうちにヒュヒュっと書きます。

インターンについて

僕が行ったインターンは技術インターンシップです。

このインターンは前半一週間と後半二週間に分かれており、前半が講義、後半が実際に業務を行うというもの。

後半は相談可能と書いてある通り割りと柔軟に期日の設定が可能で、僕は時間があったので後半を一週間伸ばして一ヶ月となっています。

参加

初めはインターンではなく一ヶ月ほど夏にアルバイトとして行こうと思っていました。

しかし、インターンも薦められて迷っていると 「昼ごはんも出るよ?」 との声。

昼ごはんが出るなら選択肢は一つしか無いですね。インターンにしておいてとても良かったと思います。

前半

前半は社員の方が講師となり、6分野についての講義を受けます。

  • 1日目は Rails や TDD。Rails は初めて書いたのですが、一日ガッツリやることで軽くは書けるようになった気がします。*1
  • 2日目は Android。せっかくなので Kotlin で実装したり Realm 入れたりしました。Kotlin, やはり DataBinding (apt) 周りが厳しい。
  • 3日目は iOS。この日は台風が来たので夕方にシュッと帰ったのですが、終わった後 @tyage とハンバーガー屋に行ったら他のインターン生もいて面白かった。
  • 4日目はサービス開発。詳しくは下にありますが、コードを書かずにプロトタイプなどの作成を行いました。普段全くしないことで刺激的だった。

  • 5日目は機械学習。TensorFlow で画像分類だけは軽くしたことがあるのですが、この講義では sklearn を使いました。 mecab で自分で教師用データをいい感じに作るのが面白かった。
  • そして最終日は JS のコンパイラのコードジェネレータ。興味はあるけど普段はなかなか行わないことで、非常に面白かったです。親切なスライドのおかげでやったことなくても案外できました。(という煽り返し)

こうしてみると盛りだくさんな内容ですが、講師の方がわかりやすく解説してくださったので楽しくこなしていくことができました。

最終日に後半に進む人が発表されます。僕は事前に希望していたとおり、インフラの部署に所属することになりました。

後半

後半は実際に業務をこなしていくというもので、配属される部署によって内容は異なります。

僕はインフラ部署で、メンターの星さんの元で色々やりました。例えば構成図書いたり、サーバー増やしたり移行したり。

自分はインフラっぽいことはしたことがなくて、せいぜい家の RasPi を ansible で管理したり GCE で一万溶かした程度なので少し不安でしたが、みなさん優しく教えてくださっていい感じに業務を進めることができました。

サーバーの管理、大規模サービスでのロードバランサやキャッシュetc構成、DBのレプリ構成などなど様々なことを知ることができましたし、最後の方には大掛かりなこともやらせていただいてとても楽しかったです。

これだけ AWS でいろいろやってる会社は少ないと思うし、興味がある人はぜひ行ってみるべきだと思う。

昼ごはん

インターンに行くきっかけとなった昼ごはんですが、さすが cookpad なだけあって(?)非常に美味しかったです。みなさん行きましょう。

詳しくは下の pocke くん*2の記事を見たら良いと思います!!!!

ゆゆ式

完璧に対応してた。

その他

  • オフィス、恵比寿ガーデンプレイスにあるのだけど、恵比寿ガーデンプレイスは丘の上にあるので cookpad 社内からの景色が非常に良かった。良く窓際の人を駄目にするソファーでコード書いてました。
  • オフィスにたまにバナナが置いてあって食べれて良かった。バナナ美味しい。
  • 社内ツールがいろいろとそろっていて、環境を感じた。
    • ほぼ任意の場所で ruby が書かれていてさすがという感じ

まとめ

とにかく毎日が新鮮という感じで楽しかったです。インターン生も面白い人が沢山いたし、社員もすごい人ばっかりだった。

ruby はほとんど読んだことも書いたこともなかったし、AWS も EC2 ポチポチ立てたことがあるだけだった僕が ruby を好きになり route53 のマークを見ずに頭に浮かばせれるようになったのは完全に進捗だし、最高と言えるでしょう。ありがとうございました。

*1:実は bundle exec を初めて使った...

*2:彼はすごくて、rubyPython 書いたりしてた

RecyclerView で Drag と Swipe をサクッと実装

RecyclerView で並び換えや項目の消去をする UI を作成するには、ItemTouchHelper を用いると非常に楽です。

これを使うと、

  • 長押しからの移動で並び替え
  • スワイプで消去をする

といった処理を行えます。

Kotlin での実装

val helper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
    // どのような動きを許可するか
    // ViewHolder ごとに分ける等の場合はここで制御する
    override fun getMovementFlags(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?): Int {
        return makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)
    }

    // 動いた場合
    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
        // アイテムの位置を変更
        val button = adapter.buttonList.removeAt(viewHolder.adapterPosition)
        adapter.buttonList.add(target.adapterPosition, button)
        adapter.notifyDataSetChanged()
        return true
    }

    // スワイプされた場合
    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        // 項目を消去
        adapter.buttonList.removeAt(viewHolder.adapterPosition)
        adapter.notifyDataSetChanged()
    }

    // 選択状態が変化した時に呼ばれる
    // 選択が解除された場合 viewHolder は null になるので #clearView で操作する
    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
        super.onSelectedChanged(viewHolder, actionState)
        // e.g. 半透明にする
        when (actionState) {
            ItemTouchHelper.ACTION_STATE_DRAG, ItemTouchHelper.ACTION_STATE_SWIPE -> {
                (viewHolder as? OptionButtonsPreferenceRecyclerAdapter.ViewHolder)?.let {
                    it.binding.itemBaseView.alpha = 0.5f
                }
            }
        }
    }

    // アニメーションが終了する時に呼ばれる
    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
        super.clearView(recyclerView, viewHolder)
        // e.g. 反透明にしていたのを元に戻す
        (viewHolder as OptionButtonsPreferenceRecyclerAdapter.ViewHolder).binding.itemBaseView.alpha = 1.0f
    }
})

helper.attachToRecyclerView(recyclerView)

PhotoLinkViewer-Core/PLVOptionButtonPreferenceActivity.kt at 63fb7a73f7eaded1d8801e5a63bcc65965829b28 · nonylene/PhotoLinkViewer-Core · GitHub

こうするだけで下のように良い感じに移動・消去できるようになります。すごく便利。

補足

  • OptionButtonsPreferenceRecyclerAdapter.ViewHolder に無理矢理キャストしているのはこの ViewHolder しか存在しないため
  • notifyDataSetChagned() でもいい感じにアニメーションしているのは、以下の記事のように特定の ID を返しているため

Android Layout XML の名前空間はルート要素に定義する

たまに DataBinding を使うのですが、例えば TextViewtools:text を指定してレイアウトのプレビューを試みても上手くできないことがあって困っていました。

例えば、適当に

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <TextView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:text="hogehoge"
        >
    </TextView>
</layout>

と言ったレイアウトを作成しても、プレビューには hogehoge と表示されません。

f:id:nonylene:20160815235046p:plain

仕方がないので今までは android:text="@{text; default=`hogehoge`}" という記法を使ってデフォルト値を設定するようにしていました。

しかし、今日アプリを作っているとプレビューできているレイアウトがあるのを発見。調べてみると、 layout で tools と android を定義しているとプレビューできる ということが分かりました。

なので、今回はこう置き換えます。

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:text="hogehoge"
        >
    </TextView>
</layout>

こうすると、しっかり表示されるようになりました。

f:id:nonylene:20160815235606p:plain

レイアウトの名前空間はルート要素に定義する

他のレイアウトでも調べた結果、DataBinding とは関係なく ルート要素で tools と android を定義していないとプレビューに失敗する みたいです。

普通はルート要素に定義していたので気づかなかった。これからは <layout> でもルート要素に名前空間を置こう(自戒)。

画像取得ライブラリの Glide 使ってみた

Android で画像を表示する際、 URL からいい感じにキャッシュしていい感じに表示してくれるライブラリはいくつかあります。

有名所だと

  • Picasso
    • Square のライブラリ
  • Glide
    • 元BumpTech のライブラリ (Google のプロダクトでも使われているらしい)
  • Fresco*1

日本だとなんとなく Picasso をよく見かける気がする。

元々 PhotoLinkViewer では Picasso を用いていて、アニメーション GIF は webView で表示していたのですが、 Glide がアニメーション GIF に対応しているとのことで Glide を使ってみました。

使い方の説明は以下に詳しいです。

上に書いてあるとおりカスタムがしやすい Picasso と言った感じ*2で、インターフェースもそっくりなので適当に Picasso を Glide に置き換えるだけで動きます。すごい。

move to glide from picasso · nonylene/PhotoLinkViewer-Core@a11fe73 · GitHub

OkHttp や Volley にも対応していて、さらに GlideModule を使えば自分の OkHttpClient も使えて便利。

Integration Libraries · bumptech/glide Wiki · GitHub

アニメーションGIFについて

さて、目的はアニメーションGIFな訳ですが一筋縄には行きませんでした。

軽いアニメーションGIF(500*500程度) では軽快に動くのですが、 1980 * 1080 ぐらいになるとよくOOMで落ちてしまいます。

.asBitmap() を指定すると細かい画像の縮小ロードの設定ができるのですが、GIF だとできないので BitmapOptions.inSampleSize レベルではあまり縮小してくれない。*3

ttps://www.reddit.com/r/androiddev/comments/2tpwub/glide_35_released/co1hmsx*4

そもそもまだ縮小してデコードするのに完全に対応していないらしい。

OOM loading huge gifs · Issue #83 · bumptech/glide · GitHub

メモリキャッシュをスキップしたり、 AndoridManifest.xmlandroid:largeHeap="true" を設定すると落ちにくくはなったのですが、そこまでしても結局GIFの拡大・縮小操作やアニメーション自体が非常に重くなってしまいました。

その後結局諦めて webView で表示するようにしました。 webView だと 3000px ぐらいでも落ちることがなく、比較的滑らかです。

小さい GIF の表示にでは簡単に GIF を入れることができて非常に便利そうなので、また機会があれば使おうという感じでした。*5

その他

  • Fresco という Facebook の画像ライブラリもアニメーションGIFに対応していて多機能そうだったのですが、ダウンサンプリングにはまだあまり対応しておらず、コードも大きい等いろいろ面倒そうだったので使っていません。
  • Ion というライブラリも対応していますが、これはもうちょっと汎用的ななんでもライブラリっぽい。

*1:京都には同名のスーパーがある

*2:内部のコードは全然違いますが

*3:inSampleSize が小さい方の辺が優先されるため、横に大きい画像だと縦に表示した際に縦が 3000px ぐらいになるまで inSampleSize が 1 のまま

*4:reddit のNG避け

*5:戻すのめんどくさくて Picasso 使っていた場所はそのまま Glide にしてますが