📝

Android Basic with ComposeのUnit4で学んだことをまとめてみる - Architecture

2024/11/27に公開

はじめに

こんにちは、某SIerでSEをやっているnekorush14です。
この記事は絶賛再*n入門しているAndroid開発について、Google公式のLearning Courseを通して学んだことをアウトプットするシリーズです。

Jetpack Composeに関するCourseのUnit4で得た知見を話します。
https://developer.android.com/courses/android-basics-compose/unit-4?hl=en

前回の記事はこちら👇
https://zenn.dev/nekorush14/articles/3989bf2efe1cb5

今回はUnit4のメインであるArchitectureについてまとめます。

Architecture

  • 一般的なアーキテクチャの原則は"関心の分離"と"モデルからのUI駆動”
  • Androidで推奨されるアーキテクチャーはLayered Architecture
  • UIレイヤー、ドメインレイヤー(オプション)、データレイヤーの3レイヤー構成
  • 依存関係は以下の通り

UIレイヤー

  • アプリケーションのデータを画面に表示する役割

  • UIが更新されるたびに変更を反映する必要がある

  • 構成コンポーネント

    • UI要素 (element)
    • State Holder (ViewModel)
  • ViewModel

    • UIが使用する状態の保持と公開
    • ActivityがAndroidのフレームワークにより破棄・再生成されたときにアプリケーションのデータを保持しておく
    • Configuration Changeの際に自動的にオブジェクトを保持しているため、ReComposition後すぐに使用できる
  • UI Stateはアプリがユーザに表示する内容

    • UI要素とUI Stateをバインドした結果がUIとなる
    実装例
    data class SampleItemUiState(
        val title: String,
        val description: String,
        val archived: Boolean = false,
        //...
    )
    
  • UI自体が唯一のデータソース出ない限り、UI Stateを直接変更してはならない

    • データソース出ない場合は不変値として扱う
    • この原則に従わない場合、データ不整合やバグが発生する原因となる

StateFlow

  • StateFlowはObservableなフロー
  • 現在の状態と新しい状態の更新を発行する
  • valueプロパティを経由して現在の状態を取得できる
  • MutableStateFlowクラスのvalueプロパティに新しい値を指定すると状態を更新してフローに送信できる
  • AndroidではObservableなStateFlowをimmutableなクラスで保持するとうまく機能する
  • Backing propertyを使用するとObjectの値以外も返すことができるようになる
  • varで宣言されているプロパティはKotlinが自動的にGetterとSetterを生成する
  • valで宣言したプロパティに対してGetterがオーバーライドできる
private var _sampleString = "Sample String!"

// Getterをオーバーライドする場合
val prop: String
    get() = _sampleString

// 外部に公開するRead onlyなプロパティを作る場合
val readonlyProp: String = _sampleString
  • StateFlowの場合、MutableStateFlowなどで宣言したStateFlowのasStateFlow()を使用して初期化する

  • 一方向データフロー

    • Stateが下位に流れ、Eventが上位に流れる設計パターン
    • ViewModelがUIで使用する状態を保持し、公開する
    • UI StateはViewModelによって変換されたアプリケーションのデータ
    • UI要素がViewModelに対してイベントを通知する
    • 状態が更新されるとUI要素にフィードバックされてレンダリングされる
    • このプロセスが状態変化のたびに繰り返される
  • Screen側での使用方法

    • Screenを定義しているComposableの引数にandroidx.lifecycle.viewmodelviewModel()を指定する
    • Composableの内部でbyによりデリゲートしたviewmodelのUI StateをcollectAsState()により使用する
      • これにより、状態が変化した場合に必ずReCompositionが発生するようになる
  • Stateの更新

    • 更新する際はMutableStateFlowupdateを使用する
    • updateのlambdaで現在のStateをcopy()でパラメータを指定しながらコピーして状態を更新する

おまけ

  • Androidでダイアログを表示させるにはAlert Dialogを使用する

  • Alert Dialogは以下の要素で構成される

    • Container (ダイアログ本体)
    • Icon (Optional)
    • Headline (Optional)
    • Supporting text (ダイアログ本文)
    • Divider (Optional)
    • Actions (ダイアログのアクションボタン)

まとめ

今回はAndroidのArchitectureについてまとめてみました。
最大3レイヤー構成なので、意外とシンプルに感じました。
また、単一データフローの考え方はバグを引き起こしにくくする良い考え方だと思いました。

Unit4ですがまだまだコンテンツが残っています。
次回はNavigationの話をします。

参考資料

Discussion