はじめに
開催からだいぶ空きました(忙しくて時間がとれなかった…)が、8/19に開催されたBonfire Android #5 に参加してきました
なのでレポート的に各発表をまとめようと思います。今回のテーマは「Jetpackとサービス」ということで、Jetpackに関連する話題を中心とした発表が揃っていました。
navigationを見据えたリファクタリング~マルチモジュール化を添えて~
木内 啓輔さん (@fei_kome) ◆ ヤフー株式会社
実装・運用されている期間が長いアプリをマルチモジュール化・navigation componentsをする際に考えられていることについてお話されていました。
マルチモジュール化自体、近年トレンドになった話題で(僕はDroidKaigi 2018でマルチモジュールに関する話を初めて聴いて、そこから話題になったと感じているだけかもしれないです)、やはりそれ以前からずっと開発されていたアプリは「マルチモジュール化されることを想定していない」「モジュール分割に耐えうるような依存関係・設計ができていない」という状態にあると思っています。
それを踏まえて、実際にマルチモジュール化を実現するためUI-Presenter間の相互依存を解消するための腐敗防止層的なInterfaceを作ったりすることでnavigation componentの導入を視野に入れた切り分けを実現するといったリファクタリング過渡期の実装tipsについて紹介されていました。
マネーフォワードMEにおけるJetpackの活用事例
syarihuさん (@syarihu) ◆ 株式会社マネーフォワード
syarihuさんが以前他で発表された内容も織り交ぜながら、マネーフォワードMEがどのようにAndroidXを始めとするJetpackの導入を行っていたのか、導入から1年経って何が変わったのかについてお話されていました。 マネーフォワードMEでのJetpackの導入は
- 手入力画面のリファクタ、設計変更を含めたJetpack導入
- 月額課金機能へのPlay Billing Library導入
- LiveData、ViewModel、Lifecycleを用いてBillingViewModelを作り、どの画面でも課金機能を作りやすい状況に
- 入出金履歴画面へのBottom Navigationの導入
- 複数の遷移元が存在し複雑になってしまった更新リクエストをRxJavaのBehavingProcessorとLiveDataを用いることで簡単に扱えるように
という感じだったそうです。導入を始めてからはおおよそ1年とのことで、古い機能の刷新と並行して行う機会が多かったようで設計適用のためのリファクタではなく、多くの部分に導入を進めることができたことや、このJetpackの導入、設計変更によってテストの記述効率の向上を果たせたとのことでした。
Paging Libraryでのアイテムの更新
釘宮 愼之介さん (@kgmyshin) ◆ 合同会社DMM.com / CTO室エバンジェリストチーム
Paging Libraryを使って、チェックボックスの操作といったリストのアイテムの更新をどのようにUIまで反映させるかについてお話されていました。 基本的な実装手順からよく躓くポイントとして
- アイテムがアップデートされない
- ItemRepositoryに新しいデータを保存する
- DataSourceをinvalidateして再取得を走らせる
- 更新はしたもののスクロール位置が急に最初に戻る
- initialzeKeyがPageKeyedDataSourceを使ってる限りnullになるから
- 対策としてRoomを使う
- DatabaseとDaoを作ることでDataSource周りをよしなに作ってくれる
- マイグレーションが大変、このためだけにDBを持ちたくない場合はInMemoryでも使える
- Roomを使わなくてもできる
- BoundaryCallbackを扱うItemDataProviderを自前で実装することで実現できる
- Repositoryがページ単位を、DataSourceがItem単位を扱うと考えて実装する
それぞれのやり方についてサンプルも公開されているので、気になる方は確認してみましょう。
Roomとコルーチンと私
荒木 佑一さん (@yuichi_araki) ◆ Google
Room 2.2.0-alpha02でのアップデートとして様々な機能が追加されましたが、その中でもCoroutines Flowを主眼において解説されていました。
Room自体、2.1.0でsuspend functionに対応して、coroutineで書くとメインスレッドでinsert等のメソッドを実行してもsuspendしてバックグラウンドに行ってくれる、というような解釈をしてくれるようになっており、更に Transaction アノテーションを付与することでcoroutinesが取り消されたり、エラーになったときに処理全体を取り消したりできる機能が追加されています。
Room 2.2.0では、これらに加えてCoroutines Flowに対応しており、Coroutines Flowの特徴である
- コールドストリーム(cf. Channel:ホットストリーム)
- アクセスされるまで処理が実行されない遅延評価
- コンテキスト保持
- Dispatcherを指定できる
- 例外透過
- .catchで例外を補足できる
といった恩恵を受けることができ、DB操作を監視した処理ができるようになるなどしています。
また、RoomのDaoの内部実装でどのようにCoroutinesを実行しているかという話や、Roomが非同期実行の際にトランザクション、スレッドを適切にハンドリングしていることについても言及されていました。
jetpackのNavigationと関連UIコンポーネント
樫村 実紅さん (@k_miku) ◆ ヤフー株式会社
www.slideshare.net
開発されているアプリにNavigationを導入された際のことについてお話されていました、ヤフーニュースアプリ、一つの大きい改修を行う際には一つ新しい技術にチャレンジすることを掲げているそうですね。
各画面の遷移をなめらかにするために1-Activity / n-Fragment構成を実現すること、Fragmentの遷移管理の負担を下げること、トレンドへの追従を目的としてNavigation導入を行ったということで、実際に導入する中で躓いたポイントとして
- ActionBarと連動をさせようとすると仕様に合わない
- Resource XMLに定義した文字列のタイトル反映はできるが画像やEditText、動的な文字列といったものは出せない
- 結果としてActionBarと連動させることは諦め、各画面でActionBarをそれぞれ操作することにした
- 画面遷移時のアニメーションのカスタマイズ
- NavigationUI#setupWithNavControllerを使う際、デフォルトで指定されているアニメーションしか使えない
- OnNavigationItemSelectedListenerを自前で作り、その中でNavOptionsをbuildすることでカスタムのアニメーションを設定した
- 画面遷移時に遷移以外の操作を行いたい
- 遷移したというユーザ行動等のログを取る必要がある
- 同様に、OnNavigationItemSelectedListenerを自前で作り、その中でItemのIDをみてログを送信した
という手段とをって解決されていました。
あまりにも遅筆過ぎた結果Jetpackが大リリースしてた
完全に怠慢の限りなのですが、イベント後しばらくたった9/5のタイミングでJetpackに大きなリリースがやってきて、いろんなコンポーネントがstableになったりしました。Room 2.2.0もrc1になったりしています。
先日あったca.apk #8で発表された資料を引用するのですが、Activityも1.0.0でFragmentのバックハンドリングが onBackPressedDispatcher で行えるようになっていたり、Activity(1.0.0) / Fragment(1.1.0)でLayout ID Constructorが追加され、layoutのリソースIDを引数に渡すことでsetContentView / onCreateViewを省略できるようになったり、いろんなトピックスが起きています。
Androidに限らず、この手のアップデートがすごい勢いで行われるのでBonfireを始めとした勉強会で新しい知識を気軽に知ることができるのはすごい素晴らしいと思います。インプットした知識を現場に還元し、また新たなアウトプットを生み出せるといいなと思いました。
最後に
Bonfire Androidを主催してくださったヤフーさん、本当にありがとうございました。レポートを書くのが非常に遅くなってしまい大変申し訳ありませんでした… :bow: