Jetpack Composeを本番投入しました(マルチモジュール編)
リサーチ・アンド・イノベーションの高田(tfandkusu)です。Androidエンジニアをやっています。前回はAndroid版CODEアプリにおけるJetpack Compose使用画面でのViewModel設計について解説しましたが、今回はマルチモジュール構成について解説いたします。
3部構成
この記事は3部構成の第2部です。
- ViewModel編
- マルチモジュール編(今回)
- 画面遷移編
Jetpack Composeのプレビューを速くする
Jetpack Composeを採用した画面ではマルチモジュールの構成を変更しているのですが、そのモチベーションはJetpack Composeのプレビューを速くするためです。DroidKaigi/conference-app-2021でも言及されている通り、プレビュー対象のComposable関数の依存モジュールを必要最低限にすることによって、プレビューを速くしています。1度フルビルドが完了した後のプレビューの再表示のためのビルドは、3〜5秒ほどで完了します。(M1 Max, 64GBメモリで計測)
Jetpack Compose不使用画面のモジュール構成
Jetpack Composeを使っていない画面のモジュール構成は前々回に解説したアーキテクチャに沿って、このようになっています。
機能別モジュールにはホーム画面や買い物登録など、大まかに分類された各機能のActivity/Fragment、リソース、ViewModelとUse Caseのクラスを格納しています。各機能で共通して使われるリソースやAPIエラー処理などはviewCommonモジュールに置いています。別モジュールにあるActivityを呼び出すためのActivity aliasもこちらに置いています。 このモジュール構成のまま機能別モジュールにComposable関数を実装すると、プレビューのためのビルドでrepository、localDataStore、remoteDataStoreモジュールが含まれてしまい時間がかかります。よってComposable関数を持つモジュールではそれらを含まないようにしています。
Jetpack Compose使用画面のモジュール構成
Jetpack Composeを使う画面では、機能別モジュールをこのようにpresentation、compose、useCaseの3モジュールに分けました。モジュール名の先頭に付いているsubscriptionは前回説明した繰り返し一括登録機能のモジュール群であることを表し、機能ごとにディレクトリが分かれます。
composeモジュール
Composable関数とそのプレビューを持つcomposeモジュールは、viewCommonとcomposeCommonモジュールにしか依存しないため、プレビューを速く表示できます。 ViewModelのインターフェースと固定の状態を持つプレビュー用ViewModel実装もこちらに置きます。
composeCommonモジュール
Jetpack Composeで実装する複数の機能で共通して使われるComposable関数はこちらに置きます。テーマやツールバー、エラー表示などがあります。
presentationモジュール
CODEはActivityによる画面遷移を行っているため、このようにComposable関数を使っています。
class SubscriptionListActivity : ComponentActivity() { /** * ViewModel実装の注入。Koinを使用。 */ private val viewModel: SubscriptionListViewModel by viewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { // テーマ CodeComposeTheme { // 繰り返し一括登録の一覧画面(composeモジュール) SubscriptionListScreen(viewModel) } } } }
ViewModel本番実装もprensetationモジュールに持っていて、内部ではUseCaseを呼び出しています。
useCaseモジュール
各種UseCaseクラスを持っています。ViewModel実装とUseCaseは同じモジュールでも良いと思ったのですが、適切な名前が思いつかなかったことと、今後のチームの拡大を考えるとレイヤードアーキテクチャに対する強制力を持たせた方が良いと思い、UseCase用のモジュールを作ることにしました。
まとめ
今回はCODEに対するJetpack Composeの導入について、マルチモジュール構成について説明しました。Composable関数とそのプレビューに必要なクラスのみをモジュールに切り出して、そのモジュールが依存するモジュールを最小限にすることで、許容範囲の3〜5秒ほどのプレビュー表示時間を実現しました。それによってJetpack Composeを導入したことで、開発体験が下がる事態を防ぐことができました。 次回はActivityやJetpack Navigationなど、複数のアプローチがある画面遷移について、CODEはどのような事情があって何を選定したかの記事を公開予定です。
Androidエンジニア募集中
弊社リサーチ・アンド・イノベーションでは、例えば開発体験にもこだわりがあり一緒に向上して頂けるAndroidエンジニアを募集しています。