Index
1.プロダクトレベルで必要になるJetpackComposeテクニック
2.Master Of Lifecycle
3.長く生きるコードベースの「品質」問題に向き合う
1.プロダクトレベルで必要になるJetpackComposeテクニック
Android Jetpackとは
Android Jetpackとは、Android公式開発者ページにある通り、
ベストプラクティスを集めたライブラリである。ボイラープレートコード(ほぼ固定化されたよく出てくるコード)を減らし
Androidバージョンやデバイスが変わっても一貫して機能するコードの作成を助け、
コーディングの負担を軽減する。
Android Jetpackは、4つのカテゴリに分類される。
JetpackComposeとは
Jetpackに含まれる、ネイティブUIをビルドするためのAndroid最新ツールキット。
AndroidのUI開発を簡素化し、加速する。
少ないコード、パワフルなツール、直感的なKotlinAPIを使用して
アプリをすぐに動かすことができる。
JetpackComposeのサンプルを用いて、画面遷移の実装を行う
JetpackComposeサンプル | Activity生成数 | 画面遷移 |
---|---|---|
Crane | 複数Activity | Activity遷移、Fragment差し替え |
Jetchat、Jetsurvey | 1Activity | Fragment差し替え |
JetNews、JetCaster、Rally、Owl | 1Activity | Compose |
補足)
Activity・・・一つの枠を表示するのに向いている
Fragment・・・タブやマルチメイン画面など、複数の枠を表示するのに向いている
Activity上で動く
Compose・・・状態ごとに画面を持つという形式
JetpackComposeにおける、必要な機能の検索手順
①リファレンスをみる
・androidx.compose.*の Top-level functions summary
・androids.compose.materialのComponents
必要な機能の検索は、リファレンスをみて探すのが一番早い
必要なパッケージは大体、androidx.compose.foundationか、androidx.compose.materialにある
URL)
・androidx.compose.foundation
https://developer.android.com/reference/kotlin/androidx/compose/foundation/package-summary?hl=ja
・androidx.compose.material
https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary?hl=ja
②accompanistにないか調べる
URL)
https://github.com/google/accompanist
・JetPack Composeの便利ライブラリ集
・Swipe to Refresh
・Pager
・…
もともとはGoogle開発社個人のリポジトリにあったものだが、Jetpackの方に移動されてきた
本体にない時はここをチェックする
時々みると新しいものが増えていたりする
③Kotlin Slackのcomposeチャンネルで検索する
URL)
https://kotlinlang.slack.com/
※https://kotlinlang.org/community/ から招待をリクエストできる
どうもそれらしいものがない、または、ありそうだけどどれか良くわからない場合に調べる
④JetpackComposeのサンプルコードを読む
URL)
・Android Coad Search
https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/
JetpackComposeの機能はサンプルが用意されていることが多い
Kotlin slackやstack overflowで見つけた機能のサンプルがないか
Android Code Searchで調べる
それでも見つからない場合はsampleでありそうな名前(materialdesignなど)で調べる
accompanistで見つけた名前などで検索すると引っかかることもある
⑤JetpackCompose Roadmapをチェックする
URL)
https://developer.android.com/jetpack/androidx/compose-roadmap
今後の実装予定が公開されている
・自分で実装するか、用意されるまで待つかの判断材料になる
それでも見つからない場合は、リリース予定のロードマップをみる
それでも見つからない場合は自分で実装するか、3rdParty製ライブラリを利用する
UIパーツはライブラリを探すよりかは自分で実装した方が速い
それ以外は大体は本体かaccompanistかcoilで対応している
まとめ
JetpackやJetpackに含まれるJetpackComposeを使うことで開発スピードを上げられる。
2.Master Of Lifecycle
ライフサイクルとは
例えばActivityにはライフサイクルというものがあり
Activityの生成から破棄までの周期(状態遷移)を表したものである。
Activityのライフサイクル
ライフサイクルを理解した方が良い理由
ライフサイクルを理解しなくても、「動く」アプリを作ることができる
しかし、「より良いアプリ」を作るためには理解しておいた方が良い
・不要に端末リソースを消費しない
・無駄なネットワーク通信をしない
・クラッシュしない
不要な端末リソース消費として、メモリリークがある
メモリリークとは確保メモリの解放漏れのことであり、例えば以下により起こる
・生存期間が長いインスタンスAが、生存期間が短いインスタンスBを強参照する
・非同期処理のキャンセル忘れ
メモリリークを起こさないために
・不必要になったタイミングでインスタンスの解放、処理を終了する必要がある
・Androidでは、ライフサイクルを利用することで、適切なタイミングで解放することができる
Activityのライフサイクルを適用する
・Activityにはライフサイクル実装を行うために、コールバックメソッドが定義されている
ライフサイクルの表にもある、以下メソッド
onCreate()、onStart()、onRestart()、onResume()、onPause()、onStop()、onDestroy()
・アクティブ・非アクティブの状態変化を受け取ることができ、適切に処理を実行することができる
例)ライフサイクルに従った、UIの更新
UIの更新でやりたいこと
・UIの構成に必要なデータを、非同期に取得し、取得したデータをUIに反映したい
・常に最新のデータを保つ
・画面が非アクティブの時はUIを更新しない
・画面回転など、Activity再生成時にデータを保持する
ViewModel
・UIの構成に必要なデータを保持するクラス
・Activityが再生成されても、データを保持することができる
・ViewModelを使うことで、Activityの再生成、プロセスデスを乗り越えてデータを保持できる
・次に、そのデータのUIへの通知方法について考える
LiveData
・値が変更されたら、ライフサイクルの状態に応じてUIに通知する
・アクティブ時に通知する
・非アクティブ時には通知されない
LiveDataビルダー
・必要なデータをコルーチン(非同期処理)を使い、取得することができる
・指定した時間非アクティブになったら、処理を終了する
LiveDataのまとめ
・LiveDataを使うことで、ライフサイクルに合わせたデータ更新が可能になる
・ViewModelと組み合わせると、Activity再生成時に、効率良く画面復帰ができる
・LiveDataビルダーも使うと、処理のキャンセルもできる
まとめ
・ライフサイクルは「良いアプリを作る」ために必要
・アプリをライフサイクルと協調して動かすことで、端末のリソースを効率良く使うことができる
・ViewModel、LiveData、LiveDataビルダーを使うことで、UIの更新を効率良くできる
3.長く生きるコードベースの「品質」問題に向き合う
はじめに
現場において大規模開発チームで何チームもある場合、こういうことがある
・他のチームが書いているコードの内容がよく分からない
ここでは、LineのAndroidクライアントチームが行っていることを紹介する
話の前提
・スクラム開発
・バージョン管理にGitを利用
↓TEAM Aの中でやっていることはわかるがTEAM Bの人にはわからない
↓新しいルールやライブラリを作っても特定のチームは反映できていない状況が起こる
これらを解消するために、コンテキスト(歴史や背景)を記録していく。
これは、世間一般で行っていることだが
LineAndroidクライアントチームでは、加えて
・ソースコードについてコンテキストなしで読めるようにする
取り組みを行っている
・チームの垣根を壊して、チーム間での知識共有、技術共有、
開発文化の共有を行っている
具体的に落とし込んだのが次の5つになる
・2フェーズレビュー
・構造ドキュメント
・コード作成のベストプラクティス作成
・技術コンサルタント
・レビュー委員会
チーム内のレビューでは、以下のような問題がある
・依頼者とレビュー者が固定化されてしまう
・チームをまたがったレビューが行いにくくなる
これを解決するためにレビューを2段階に分ける
①まずチーム内で知識のある人が1stレビューを行う
②次に、プルリクエストを検知するbotを通してランダムで
slack通知して選出された他チームの何も知らない人に
2ndレビューをしてもらう
→背景なしにコードが読めるかどうかをチェックすることができる
2フェーズレビューの利点として、
①レビュアー同士でフィードバックができる
→1stレビュアーで何か見落としがあった場合に、
2ndレビュアーが1stレビュアーにフィードバックすることができる
②チームの垣根を超えたレビューをすることになるので
チームの垣根を超えた知識共有ができる
・2フェーズレビューを使うことによって、プルリクエストの範囲で
コンテキストなしにコードが読めるかチェックできる
だが、プルリクエストを複数合わせた「構造」で見たときに分からない
→個々ではわかるけど、まとまると理解できない
それを解決するのが、次の構造ドキュメント
構造ドキュメント
構造ドキュメントは実装を始める前にドキュメントを書く
これにより技術的な問題点を明確にできる
ウォーターフォールの詳細設計との大きな違い
→フォーマットがないこと、好きなものを好きなだけ書く
もう一つの大きな違いとして、実装して問題がある場合、
構造ドキュメントに立ち戻って修正する
構造ドキュメントに書くこと
・やることとゴール
・背景
・クラス図(抽象図、具象図)やモジュール図
・Modelクラスの定義
→開発の規模に応じて省略
・タスクで、セキュリティ・プライバシー・パフォーマンスについて懸念点がある場合は、
その旨をドキュメントに残す
LINE Androidクライアントチームが構造ドキュメントを実際に導入して得られた知見
①構造ドキュメントを必須とするべきはない
1、2日で終わるようなタスクでは必須にしてしまうと
かえって生産性が落ちてしまう
→例えば2週間以上とか中・大規模のタスクで構造ドキュメントを書くようにするといい
②よく話し合ってから書く
話し合ってから書くようにするとより手戻りが少なくなる
③構造ドキュメント自体が背景などを示すコンテキストになる
プルリクエストのdiscriptionなどにリンクとして残しておくと、あとあと役に立つ
2フェーズレビューや構造ドキュメントは開発プロセスを改善するのに役立つ
だが、実際のコード改善はこれではできない
→LineのAndroidクライアント開発においては、発表が8hにも
及ぶコード作成のベストプラクティスが作成されている
ベストプラクティスを用いて実装することにより、
後々のリファクタリングの効率が上がる
例)以下、Account TypeによってUIで表示するBackgroundとAccount Iconを切り分けたい
関数を作成する方法として、Account typeで分ける方法とUIで分ける方法がある
結論を先に言うと、UIによって分けるべきであり、Account typeで分けてはならない
なぜそうした方がいいのか
→読みやすさ、外的要因に左右されない、
将来のリファクタリングのしやすさ
以下のCase1はAccount Typeで関数分けした
→関数名を見ても何がしたいか分からない
以下のCase2はUIで関数分けした
→関数名を見ると何をするかが分かる
2フェーズレビュー、構造ドキュメント、ベストプラクティス作成
これらは全てのチームに採用してほしいが
全てのチームが全てのルールを更新するのは難しい
→これを解決するのが技術コンサルタント
技術コンサルタント
シニアエンジニアがチーム内でコードレビューを行うが
その際、コードだけではなく、知識共有やプロセスの改善点も
フィードバックする
レビューを受けた人は、構造ドキュメントやソース構造を修正する
→コードだけでなくプロセスや構造を覚えスキルアップする
レビュー時の観点
①プロジェクトルール
関係者の集まり方が正しいか、プラットフォームの使い方が正しいか
②タスクのマネジメント方法
話し合いの仕方、構造ドキュメントの書き方、スケジュールの改善の仕方
③アーキテクチャデザイン
レイヤーの切り方が正しいか、依存関係の貼り方が正しいか
④コード詳細
名前の付け方、ロジックのフロー
技術コンサルタントで影響するのは特定のチームでしかない
より効率的にチーム間で知識を共有するためにレビュー委員会を行う
レビュー委員会
やること
・チームに属さないシニアエンジニア数名を配置し
すでにマージ済みのプルリクエストを各チームから送る
それをレビューしてフィードバックする
・シニアエンジニアは1週間に1回これをレポートとしてまとめ
全チームに共有する
まとめ
・2フェーズレビュー
チームの垣根を越えて知識を共有できる
コンテキストなしでもコードが読めるようになる
・構造ドキュメント
コンテキスト(歴史や背景)を残す
・コード作成のベストプラクティス作成
のちのちのリファクタリングがしやすくなる
・技術コンサルタント
チーム内でシニアエンジニアの知識を共有することにより、
エンジニアのスキルアップ
・レビュー委員会
全チームにシニアエンジニアの知識が行き渡る
結果として、大規模開発でのコード品質が長い間に渡って保たれていく