📚

Androidでマルチモジュール

2022/01/21に公開

Androidでマルチモジュールを実践してみました。

サンプル

https://github.com/usk-sample/AndroidMultiModuleSample

モジュールを作成

モジュールはAndroid Libraryとして作成します。
Android ライブラリの作成
こちらに詳しく説明されていますが、ここでは簡単な手順を記載します。

  1. File > New > New Module
  2. TemplateにAndroid Libraryを選択
  3. モジュール名・パッケージ名を入力
  4. [オプション]File > Project StructureでJava 11に変更

モジュールをアプリに追加する

作成したモジュールをアプリに追加するためには、app/build.gradleに依存関係を追加する方法とGUIを使う方法があります。

app/build.gradleに記載する方法

dependencies {
	...
	implementation(project(":module-name"))
}

GUIを使う方法

  1. File > Project Structure > Dependencies に移動します。
  2. ライブラリを使用するモジュールを選択します。ここではappとします。
  3. [Declared Dependencies] タブで+をクリックし、プルダウンから [Module Dependency] を選択します。
  4. [Add Module Dependency] ダイアログで、ライブラリ モジュールを選択します。
  5. 通常は[implementation] を選択し、[OK] をクリックします

app/build.gradleに依存が追加されます。

モジュール間での共通ライブラリのバージョン管理

androidx.core:core-ktxなどの一部のライブラリは全てのモジュール、もしくは幾つかのモジュールで使う場合があります。
今まではトップレベルのbuild.gradleでバージョンを管理していましたが、新しい機能のversionCatalogsを使用します。

こちらの記事で書いています。
https://zenn.dev/usk2000/articles/b2ca635be224e8

全体的な構成

全体的な構成は以下のようにしました

  • app: アプリ本体
    • Feature1のみimportしています
    • Infrastructureにはアクセスできません
  • Feature1: 機能1のロジックとか
    • Infrastructureのみimportしています
  • Infrastructure: APIアクセス、DataStoreなど

アクセス修飾子について

モジュール分割をしていく中で、どのクラスを公開しどのクラスを非公開にするかを考えることがありました。
kotlinのデフォルトのアクセス修飾子を調べたところ、publicだったので、他のモジュールで公開したくないクラス等にはinternalprivateを付けました。

つまづきポイント

APIリクエストからKotlin Flowへの変換

Kotlinには、LiveDataのような機能としてFlowがあります。今回、APIクライアントとしてRetrofitを使いましたが、Flowに変換する部分を書くのに時間がかかってしまいました。

https://developer.android.com/kotlin/flow

解決策として、こちらの記事を参考にしました。

FlowからLiveDataへの変換

こちらの記事に書かれているように、ライブラリの追加が必要でした。
https://stackoverflow.com/questions/61417190/unresolved-reference-aslivedata-while-converting-flow-to-livedata

androidx.lifecycle:lifecycle-livedata-ktx

ViewModel内でcorutineを使うために

viewModelScopeは以下のライブラリにありました。

androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0

このように使っています。

    fun listRepo(user: String) {
        viewModelScope.launch {
            feature1Logic.listRepos(user)
                .collect {
                    _repos.postValue(it)
                }
        }
    }

ViewModelの作成

ViewModelの初期化方法についても、少し前から変わっていました。

https://developer.android.com/topic/libraries/architecture/viewmodel?hl=ja

viewModels()のところがなかなか見つからなかったのですが、以下の2つのライブラリが必要でした。

androidx.activity:activity-ktx:1.4.0
androidx.activity:fragment-ktx:1.4.0

以下のように使用しています。

    private val viewModel by viewModels<MainViewModel>()

Discussion