nashcft's blog

時々何か書く。

DroidKaigi 2020 アプリ開発 contribute の思い出

私が Android アプリ開発に携わるようになったのが2017年後半からで、それから迎えた DroidKaigi は 2018, 2019, 2020 と今年で3度目になる。今年は残念ながら中止になってしまった*1けど、自分にとっては公式アプリに初めて contribute した年でもあるので、そのことについての振り返りを残しておこうと思う。

DroidKaigi 2020 公式アプリ

github.com

DroidKaigi では Play Store を見る限り2016からイベントのスケジュールアプリを毎年開発していて、大体開催1ヶ月前くらいにソースコードGitHub で公開され、オープンソースプロジェクトとして開発に参加できるようになる。2018, 2019の時はコードを眺めるくらいしかできなかったのだけど、今年はそろそろ contribute してみたいなと思っていたところに偶然いい感じの issue が流れてきたので contribute することができた。

送った pull request

今回送ったのは5つ。

github.com

github.com

github.com

github.com

github.com

以下それぞれの pull request について簡単にまとめる。

Automate Dagger injection & Use Fragment LayoutId constructor #618

最初に取り組んだもの。Activity や Fragment に対する injection を DaggerAppCompatActivityDaggerFragment を使うのではなく、architecture-components-samples にある以下の実装を使った方法に切り替えて、そのついでに Fragment の View 生成を androidx.fragment の 1.1.0 から導入された LayoutId constructor を使ってコンストラクタに layout の recource ID を渡す方法に変えたよ、という変更。

github.com

AppInjector は、大雑把にいうと Activity や Fragment に injection 対象として指定した interface (ここでは HasAndroidInjectorInjectable) が実装されていたら injection を行う、という実装をした LifecycleCallbacks を Application や 各 Activity (の FragmentManager) に仕込むというもの。利用する側は AppInjector#initialize でApplication に対して ActivityLifecycleCallbacks を登録するだけで良く、 FragmentLifecycleCallbacks の登録は ActivityLifecycleCallbacks の中で行ってくれる。

実は会社で触っているアプリで AppInjector を使っていて、使い方や機構などをそれなりに把握していたので、Dagger 関連の変更とはいえ私にとってはそこまで難しいものではなくラッキーなタスクだった。これのおかげで今回 contribute ができたといってもいいかもしれない。Fragment の対応は、issue を見つけたときの twitter 上での会話とか過去のコミットを見た感じこれを通して本当にやりたかったことはこっちかなって思ってついでに変更した。これは pull request 分けても良かったなーと思っている。

余談だが最近 DaggerAppCompatActivityDaggerFragment でもコンストラクタに layout ID を与えて View の生成をできるようにする pull request が merge されたので、次のバージョンで AppInjector を導入しなくても各 Activity/Fragment で injection の処理を記述せず、かつ LayoutId constructor の機能を使えるようになるはず。

github.com

そういえば AppInjector にライセンス表記とかのコメントを足すのを忘れている...

Groupie 2.7.2 #677

Groupie のバージョンを上げること自体は実際は手段の方で、目的は 2.6.0 で導入された Item#hasSameContentAs を使って同値判定の処理を簡素化する、という変更。

Groupie は内部で DiffUtil を使っていて、 DiffUtil.Callback#areContentsTheSame の判定に2.5.xまでは equals を使っていたので、同一の Item で中身も一緒の場合には再描画をさせたくない時は equals の override が必要になっていた。これが Item の実装によっては割と悩ましい問題となることもあって、その辺については以下の記事が参考になる。

qiita.com

DroidKaigi アプリでは元々この equals の実装のために EqualableContentsProvider という interface を用意していたが、Item#hasSameContentAs の登場によって equals の override をしなくても DiffUtil における同値判定を行えるようになったので、EqualableContentsProvider まわりの実装を全てそちらに移した、という内容になる。ちなみに、 Item#hasSameContentAs のデフォルト実装は equals を呼び出すだけなので、2.5.x 以前から 2.6.0 以降にアップデートする時に影響が出ないようになっている*2

Groupie は2018年末頃から半年強アップデートがなく死んだかと思われたが、昨年8月にメンテナが増え、それ以降はそこそこ活発に開発が進むようになった (最近はまた落ち着き気味だけど)。

github.com

Adjust line spacing of the description in about page #703

テキストの行間幅の設定が漏れてたので修正したもの。

Make pull request CI failed when test tasks failed #715

Pull request のCIで使ってた CircleCI のジョブが失敗してるし、失敗してるのに status check が passed で返ってきてしまうので、失敗した時は失敗と返すようにして、併せて失敗している部分を修正する、という pull request。ジョブの失敗の内、依存ライブラリを前もってダウンロードできてなかった方は結局 offline mode を外すことで対応したのだけど、これは依存を全てダウンロードするタスクを作って解決できたらよかったのだけどなあという思いが残っている。何か方法がないかGradle 力の高い人の意見を聞いてみたい。

Add style Theme.DroidKaigi.ActionBar for dark theme #732

OSSライセンスの一覧表示を Google が提供している oss-licenses-plugin で実装していて、そちらで別の問題があって issue が作られていたのだけど、そこで一覧が真っ白になってると報告されてそれを修正した pull request。Dark theme 向けの Theme.DroidKaigi.ActionBar の定義がなかったので、dark theme になってテキストの色などが白系になったのに背景などに light theme の時と同じ白色が当てられてしまったため。

おわりに

最初の pull request を出す前は何か簡単なものでも1つくらいできればいいなあ程度に思っていたが、最終的に5個送っていた。1つ目が merge されたり awesome label を頂いたりして楽しくなったのもあるが、DroidKaigi それ自体だけでなくこの公式アプリ開発も期間中は多くの人が活動していて一種のイベント感があり、開発に参加しやすい雰囲気があると感じたのも一因だったように思う。これは Live 配信された opening talk でも話があったように、DroidKaigi アプリ開発で初めて OSS に contribute したという人が増えたというところからも感じられた。

これからの1年は DroidKaigi 界隈にとって難しい状況になると思うのであまり暢気なことを言うべきではないかもしれないが、またこうやって来年もアプリ開発に contribute できたらいいなあと思っている。

*1:8/22 に Kotlin Fest と一緒に DroidKaigi 2020 Lite として開催される https://youtu.be/IwHw7vrFwSE?t=4260

*2:ただし別の箇所で breaking change が発生しているので注意