アプリエンジニアのくまもん(YOUTRUST/X)です。2023年9月14日(木)〜9月16日(土)にかけて行われたAndroidカンファレンス、 DroidKaigi2023 に参加しました。
今YOUTRUSTでは、Androidネイティブによる開発ではなく、Flutterによるアプリの開発をしているというのもあり、当初参加するつもりではなかったのですが、セッションのリストを見ていると、プラットフォームに関係なく持ち帰れる知識も結構多いんじゃないかと思い、参加することに決めました。
実際、Flutterに関するセッションや、クロスプラットフォームツールに関するセッション、自動テスト、パフォーマンスチューニング、コードレビュー、Material Design についてなど、プラットフォームに関係なくアプリ開発という枠で活用できそうな知識が多く、普段の業務にも活かせるのではないかと感じました!
以下、時系列順に聴講したセッションをご紹介します。
- DAY1
- これで安心! Compose 時代の Don’t keep activities 対応
- Unleashing the Power of Android Studio
- モニタリングでパフォーマンス改善入門
- Jetpack GlanceではじめるMaterial3のColor
- Day2
- Flutterにおけるアプリ内課金実装 -Android/iOS完全なる統一
- Androidアプリの良いユニットテストを考える
- 突撃!隣のコードレビュー
- Material 3 やめました
- 企業ブース
- Day3
- おわりに
DAY1
これで安心! Compose 時代の Don’t keep activities 対応
感想
構成変更やOSのメモリ最適化によって発生するActivityの破棄にどう対応するか、Compose が出てきたという背景も踏まえて紹介されていました。
そもそもActivityが破棄される場合にはどんな場合があるか、といった丁寧な分類から、 Compose で利用できる rememberSaveable
関数の紹介などをされていました。
当日のメモ
開発者オプションの Don't keep Activities を使うと、メモリの少ない端末における挙動を再現できる
メモリの圧迫によるActivityの再生成はどのようなときに行われるか?
- アプリ内の画面遷移で Activity が生成されるとき
- アプリから他のアプリを起動したとき
- 突然電話がかかってきたりして他のアプリが開いたりしたとき
メモリの圧迫ではないが、構成変更(画面の回転、Theme、言語の変更、折りたたみ端末で画面の大きさが変更される)のタイミングでもActivityは破棄される
構成変更は Saved State API を使うまでもなく ViewModel に保存しておけばOKだが、突然アプリをKillされたときにもデータを保持したいときなどは、Saved State API ではなく永続化が必要になる
by remember と by rememberSavable
Composable 関数で by remember
と by rememberSavable
を使うと、値を保持できる rememberSavable
だとActivity が破棄されてもOK 2.7.0, 2.7.1 だと一部OSで不具合があるが、2.7.2で解決しているという問題に直面した
内部で rememberSavable
が使われている、rememberScrollState()
というのもある ViewModel用には by savedStateHandle.saveable
というのもある
Saved State API は Bundle にデータを保存するが、50KB以上のデータは保存しないほうが良いとされているらしい
Unleashing the Power of Android Studio
感想
Android Studio の機能を IntteliJ / UI Tools / Build / Inspect の4ジャンルに分類して紹介されていました。単純にお話自体が面白かったですし、ツールは存在を知っていること自体が問題解決や効率化の糸口になるのでとても参考になりました。
当日のメモ
(資料によくまとまっているので個人的に興味がある思ったものだけ抜粋)
IntelliJ
UI Tools
Build
- FlamingoからのBuild Analyzerは、ビルドが遅いのがインターネット環境のせいか(どのくらいキャッシュが影響しているか)など内訳を見ることができる
- Pluginというのを選ぶと、どのプラグインが時間を使っているかなども分かる Giraffe からだとGradle Syncでのダウンロード統計も取れる
Inspect
- Network Inspector traffic interception
- ステータスコード、応答ヘッダーや本文などの通信内容がわかるほか、監視したいルールを用意してレスポンスを書き換えることもできる
モニタリングでパフォーマンス改善入門
感想
アプリのパフォーマンスの分析するための様々なツールが紹介されていました。要素が多くついていくのが大変でしたが、学びが多いセッションでした。
パフォーマンス分析関連の用語の使い分けや、パフォーマンス分析の分類について触れられているのも面白かったです。
当日のメモ
パフォーマンス関連の用語、微妙な違いがある
- ジャンク
- フレーム落ちのこと
- フリーズ
- フレームのレンダリングに700ミリかかる
- ANR
- UIスレッドが長期間ブロックされて起きる 入力イベントに対する応答が5秒以上
- BroadcastReceiverの応答が10秒以上
3つのパフォーマンス分析の方法
パフォーマンスの分析の仕方は3つに分類できる
- 受け身テスト
- ざっくりと事象の確認
- 手動テスト
- 具体的な事象の確認
- 自動テスト
- 定期的に回して、改善後に維持ができているのかの確認
受け身検査
受け身検査は Logcat でできる。以下のようなタグでフィルターして見る
- tag: Choreographer Frame
- Skip時に流れる
- tag: ActivityManager
- ANRの発生時に流れる
- tag :activityTaskManager
- Activityの起動時間がわかる
- tag: OpenGLRenderer
- mainThreadが700ms以上遅れる(フリーズする)したときに流れる
手動検査
Manual Test(手動検査=問題のデバッグ)は、 受け身テストより詳細な、具体的にはPerfettoやAndroid StudioのProfilerを使ったものを指す
Perfetto
PerfettoはLinux kernel の trace が可能で、Androidアプリ自体だけじゃなくて他のプロセスの様子も見れる
開発者オプションの中に、システムトレースという項目があり、これを使うとperfettoのシステムトレースファイルを作ることができる。下スワイプのメニューからトレースを記録というのを選択すると使える
Android Studio Profiler
adbで接続している場合にオンタイムで確認が可能(ただし対象アプリのみ)ジャンクの様子も見やすい
Android Studioの Profiler のほうがどちらかというと手軽
自動検査
自動検査は実行時間の平均時間などが分かるので定期的に回すことで悪化したタイミングが分かりやすい
MacrobenchmarkとMicrobenchmarkというのがあり、 Macrobenchmarkは起動、複雑な操作、比較的大きな領域を測定する Microbenchmarkは個々の関数を測定する
そのほかのツール
Android Vitals
Android Vitalsで見れるユーザーが認識したクラッシュ率、ユーザーが認識したANR率は重要な指標で、これが守られていないとPlayストア上でアプリの表示が間引かれる、適切に機能しないという表示をされてしまう可能性があるらしい
Android Vitals で見れるほかの指標には、
- スタートアップ時間(コールドスタートアップ・ウォームスタートアップ・ホットスタートアップの時間)なども見れるらしい
- 権限の拒否率
- ANRが起きたときの詳しい情報
などがある
よく使われているFirebaseCrashlyticsでできないがAndroid Vitalsではできることとしては、SDK初期化よりも前に発生した起動時のクラッシュや、Android12以前のANRが見れることが挙げられる
逆に、GooglePlayからインストールされたGoogle認定デバイス上のアプリのみしか制約というか特徴はある
Firebase Performance Monitoring
SDKを入れるとHTTPネットワークにかかっている時間や、アプリ起動の時間などを自動計測してくれる 最近7日間でどのくらい変化があったかも表示してくれる 匿名化されたピックアップ情報(処理の実際の所要時間、ネットワークの時間)も取得できる
JankStats
androidx で提供されているα版のライブラリで、Windowを監視して、Listenerに情報を送ってくれて、ジャンク情報(フレームの開始時間、時間など)が確認できる
補足
セッションの内容はアプリパフォーマンスガイドを参考に構成されているとのこと
Firebase Performance Monitoring と Macrobenchmark / Microbenchmark に関しては、2日目のセッション「パフォーマンス管理ツールの活用: Firebase Performance MonitoringとMacrobenchmarkを駆使してJetpack Composeを導入するまで」でもどのように活用したかが触れられていたので参考になりそうでした。
Jetpack GlanceではじめるMaterial3のColor
感想
Material Design についてのおさらいと、Jetpack Glance を使って Material Design 3 に対応したウィジェットを作る方法についてのセッションでした。
Material 3 の特徴について学び直せたのと、 Jetpack Glance を使ったことがなかったので、デモが面白かったです!
Dynamic Colors に関する扱いが難しいというところに関しては、 Day 2 の「Material 3 やめました」で紹介されていたものと共通するものがあるなとも思いました。
当日のメモ
Material Design の歴史をおさらいすると、以下のような流れがあった
- M1(2014)では、紙からインスパイアされた、基本的な概念が提唱された
- M2(2018)では、プロダクトブランドに応じたカスタマイズなどが強化
- M3(2021)では、アクセシビリティの強化やユーザーに合った一貫性のある体験の提供を行えるようになった(Material You)
M1/M2では、WCAGのコントラスト達成基準に配慮した適切な配色を行うのが難しいという問題があり、M3はこの基準に配慮した色パレットを生成できるようになった
Jetpack Glance を使うと、Composeを使ってウィジェットを作ることができる Glance が Composable を RemoteViews に変換してウィジェットに表示してくれる
長らくアルファだったがバージョンつい先週1.0.0になった
実際にGlanceを使ったウィジェットを作る場合のプロジェクト構成の紹介と動作デモ
Material You の Widgetは置く場所によっても色が変わったりする
M3 Color の利点
M3導入の課題
- 1から導入する場合はDesign Systemをいちから作ることになるため、対応は重めになる
- 利用したいブランドカラーとカラーパレットが合わない調整が難しい
- 実質Android12以降でないと使えない
- Dynamic Colorを使ったからといってUXの向上につながるかどうかは検討が必要
Glanceに関しては、Dynamic Color前提の構成になっており、本体のアプリとある程度独立しているので、GlanceにのみM3を導入するというのもアリかも
Day2
Flutterにおけるアプリ内課金実装 -Android/iOS完全なる統一
感想
スタディプラスさんでは、Android ネイティブから Flutter へのリプレイスを行ってらっしゃるらしく、 in_app_purchase を使ってアプリ内課金を実装した際に得られた知見をまとめたセッションでした。
Android ネイティブで実装したときとの対比や、よく使われている状態管理ライブラリである Riverpod を組み合わせて実装する方法などがまとめられているのがユニークな点だと感じました!
当日のメモ
Studyplus では Flutterでアプリ内課金を実装している
Flutterの in_app_purchase のAPIとAndroid ネイティブAPIとの対応がどうなっているのか解説
Flutterで「購入/復元/アップグレード/ダウングレード」を行うために必要なコードの一部を状態管理を含めて紹介
iOS で追加で対応が必要になった部分についての紹介
Androidアプリの良いユニットテストを考える
感想
アプリの自動テストに関しては個人的にも長年苦しめられており、理解を深めたく聴講しました。
そもそもテストを書きたいのは何故かという話から、それに対して良いユニットテストの特徴とは何かという整理をされていました。
Robolectricと実機テストの使い分けの話や、テストダブルを使うことに対するメリットとデメリットについての話があったのも面白かったです。
個人的にもテストダブルを用意すること自体が意外とコストと感じる場合も多い反面、具体的にどのようなときにどのようなデメリットがあるのかうまく言語化できていなかったので、思考が整理されてよかったです。
資料内で参照されている 単体テストの考え方/使い方 という本が良いという話は社内でも出ていたのですが、改めて読んでみようかなという気持ちになりました。
当日のメモ
なぜテストを書きたい?→アプリの変更が容易な状態を保つため
ユニットテストは、結合範囲が広いテストが持つ課題をクリアする
ソフトウェアの変更が容易な状態にテストがどう貢献する?
- テストが開発者から信頼されている
- テストをグリーンに保つコストが低い
- テストを保守するコストが低い
良いユニットテスト
- 再現性と独立性がありテストが安定している
- 迅速なフィードバックを得られる
- テストしたい箇所のテストを実行するのが容易
- リグレッションを検知できる
- テストによる誤検知が少ない
- テストコードが保守しやすい
自動テストの分類
- Pure Local Test
- 実機やエミュレータを使用せずに、開発マシンから実行できるテスト
- Robolectric Test
- Instrumentation Test
- 実機やエミュレータを使って実行するテスト
Instrumentation Test では実行速度に加えて端末と接続するコストが追加されるため、Robolectric Test と1件あたりのテストケースの実行時間が同じだった場合でも、2件目以降の実行処理時間に差が出たりして、トータルの実行時間に差が出てくることがある
そのため、できるだけ実行時間の短い実行方式を選べるようにすることで、自動テスト全体の実行速度を最大化できる
テストダブル
テストダブルを使うことで、テストできる範囲が増える一方、リグレッションの検知の失敗や、テストが失敗しやすくなる原因にも繋がるため、トレードオフを考えることが重要
改善するテクニック
- 再現性を下げるためにDI等を利用する
- Humble Objectパターンの適用
- テストダブル以外の方法の検討
- テストデータの生成をまとめる
- 何をテストしているか理解しやすいようテストコードも保守性を意識する
突撃!隣のコードレビュー
感想
「DMMポイントクラブ」「DMM TV」「DMMブックス」の3つの開発チームの事例を元に、実際に行われているコードレビューの流れや、チームで工夫していること、改善していきたいこと個人で取り組んでいること、実際に使っているPRテンプレートなどを紹介されていました。
紹介されている工夫やテクニックなどは、自分の所属しているチームや自分でも実践しているものも多く、課題感にも共感しました。
個人的にはもう結構長い間GitHubでやり取りしているので、工夫に関しては個人的には一度は聞いたことがある内容も多かったですが、これからやっていこうという人たちにとっては特にありがたい内容だったんじゃないかなと思います。
当日のメモ
- コードレビューの現状や工夫していることを紹介
- PRを小さくする
- CIを利用する
- 課題
- レビュー品質の偏りがある
- やっていきたいこと
- レビュー等を通じて共通認識を増やしていく
Material 3 やめました
感想
Material Design3をやめて独自のデザインシステムを構築することになった際の話と、実際に独自のデザインシステムを構築したときの実装の紹介などをされていました。
独自のデザインシステムといったものの、そもそもMaterial Design 3 を適用していたプロジェクトだったというのもあるからか、Material Design 3 の公式実装をそのまま使っていないというだけで、Dynamic Color 以外のコンセプトはうまく転用されている部分も多いなとも思いました。
デザインシステムがあること自体は基本的に好ましいことのはずなのですが、デザインシステムでトークンをセマンティックに丁寧に定義して行った結果、逆に運用しづらくなる場合もあるんだなあということも実感できて、デザインシステムというものを運用すること自体の利点や難しさに対する解像度も少し高まったと感じました。
当日のメモ
去年M2からM3に移行するセッションをやったが、M3をやめて独自のデザインシステムを構築することになった
Design Tokens はプラットフォームに依らない値であり、M3では md.ref.palette.secondary90
のような.
区切りのフォーマットで記述される
md が デザインシステムの名前、 .sys が デザイントークのtype、 .plalette.secondary90 がそのトークンの役割の名前
type には以下の3種類がある
- Reference Token
- System Token
- Component Token
System Token にはColor、Typography、Shapeがある
M3を使ってみた最大のペインポイントは色で、思った色が指定できない。ダークモードの対応がM2から変わっている
独自のデザインシステムではM3のComponent Token以外の概念を踏襲しつつ使っている
System Token のおすすめ初期設定と、実際にM3を踏襲したデザインシステムを実装する方法の紹介
企業ブース
チームや開発の様子に関するクイズや(ヤフーさん)、Androidに関するクイズ(スタメンさん、メルカリさん)など、クイズ系のコンテンツを用意されているブースがたくさんありました。
LINE さんのブースでは、あえてツッコミどころを設けたコードに参加者が指摘の付箋をつけていくという Code Review Challenge というのが開催されていて、個人的に面白いと思いました。
公式で配布されているパンフレットにスタンプラリーがついてきており、回りやすい設計になっているのも素晴らしいなと思いました(運営目線)。
他にも、豪華な商品がアンケートやくじ引きでもらえるブース(dipさん、ライザップさん)や、Android にまつわる同人誌を頒布してくださるブース(ピクシブさん)など、工夫が感じられる様々なブースがありました。
Day3
土曜日の開催で、午後から参加していました。コードラボや、キャリア・パネルトーク、 キャリア相談会、特定のテーマについて話せるMeetup、バリスタによるコーヒー提供などがありました。
Codelab
いくつかのトピックを選ぶことができ、自分はComposeのCodelabに取り組みました。
Composeは個人的には業務で開発したことなどはなかったのですが、この CodeLab の内容の範囲に関しては Live Edit によってかなり快適にUIを組めるなと感じました。
オフラインのCodelabなので、詰まったところを他の参加者に質問しあえるのもありがたかったです!
キャリア相談ブース
2on1で相談に乗ってもらえるキャリア相談会ブースというのもあって、なんとyanzmさんに相談に乗っていただいたりもしました。キャリア相談といっても転職の相談などをしに行ったわけではなく(笑)、以下のようなトピックを相談しました。
- どういった意識でキャリアを形成してきたか
- どういった形でアウトプットをしていくと良いか
- ブログの書き方、想定読者の決め方
- 登壇のモチベーション
2on1 で一緒に相談に行った方と上記のトピックについて相談会が終わった後にも色々お話したりもしたのも楽しかったです。
おわりに
久しぶりのオフライン参加だったのでついていけるかどうか心配だったのですが、プラットフォームに依らない知見や業務ではなかなか得られない知見もたくさん得られてよかったです!
株式会社YOUTRUSTでは、モバイルアプリエンジニアを含む多くのポジションで新しいメンバーを募集しています!