Android アプリでの Hilt の使用
2. 設定方法
はい、 ビルド が通りません。ほんま。
まじこれだけで時間消費するのほんましんど。
Java関連のエラーが出てたので、脳をタヒらせて以下を書いたらビルドが通った
compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
}
3. プロジェクトへの Hilt の追加
今のプロジェクトの構成の説明と、Hiltの導入方法について紹介。
ビルド時にファイルを自動生成するのでルートの build.gradle
と app
モジュール の build.gradle
に色々追記している感じ。
4. アプリでの Hilt
最初の設定。Applicationクラスにアノテーションを追加する。
5. Hilt を使用したフィールド注入
依存関係を注入するための実装の解説
-
Fragment
のクラス定義に@AndroidEntryPoint
- 注入する変数に
@Inject
を付与する
@Inject
が付与された変数は onAttach
で注入されるとのこと。覚えておこう。
一方で注入される側もどのようにインスタンスを生成すれば良いかを明示する必要がある。
何も考えないなら、 クラス定義に @Inject constructor()
でOK。
この辺は Dagger と同じね。
6. インスタンスのスコープのコンテナに対する設定
今度はインスタンスのスコープに関する設定。
Singletonにしてほしかったり、ActivityやFragmentのコンポーネントとライフサイクルを合わせて欲しかったりのやつ。
Singleton
指定であれば クラス定義に @Singleton
を付与すればOK。
で、今度はそのSingletonなクラスにも注入するパターンを説明してくれるみたい。
特に、依存性逆転?的なやつ(クリーンアーキテクチャの右下にある矢印のやつ)を表現するためには、インターフェースに依存させる必要があるけどそれってどうやって設定すればいいの?的な話。
7. Hilt モジュール
今度はモジュールの話。 @Module
と @InstallIn
があるらしい。とりあえず @Module
から。
-
@Module
は、Hiltにインスタンスの作り方の指示が含まれているクラスに付与する。-
object HogeModule {
みたいに 専用クラスを用意するみたい。
-
- ここに実装されている
@Provides
アノテーションが付与されている関数をもとに、注入するインスタンスを生成していくぽい。 - 特に、生成するインスタンスをシングルトンにしたいなら、
@Provides
と一緒に@Singleton
を関数に付与してあげる。逆に付与しないと、そのインスタンスに依存する要素を生成するたびに毎回新しいインスタンスが生成される。 - 特に インスタンスの生成に
ApplicationContext
が必要な場合は 引数定義に@ApplicationContext
を付与する。 - そして
@InstallIn
はそのモジュールがどのコンテナに管理されるかを指定する。- 正直何いっているかわからないけど、スコープののことだと思った。
Singleton
なら、実質Application
に紐づくので@InstallIn(ApplicationComponent::class)
を指定する。といったイメージ。
- 正直何いっているかわからないけど、スコープののことだと思った。
最後に、 Fragmet
の親となる Activitiy
にも Hilt による注入が発生することを指示しておく必要があり、同様に @AndroidEntryPoint
を付与する。
@InstallIn(ApplicationComponent::class)
を指定したところ、 ApplicationComponent
が見つからなかった。
ググったら以下が出てきた。すでに削除されている様子。
@InstallIn(SingletonComponent::class)
を使うんだって。
8. @Bind を使用したインターフェースの提供
今度は @Bind
というキーワードが出てきた。
今回のようにSingletonではなく、特定のスコープ範囲がある場合は abstract class
で モジュールを定義する必要があり、その場合は @Bind
を使うぽい( @Provides
ではなく。)
Hilt モジュールには、非静的バインディング メソッドと抽象バインディング メソッドを両方含めることはできないため、@Binds アノテーションと @Provides アノテーションを同じクラスに配置することはできません。
どちゃくそ重要なことを言われている気がする。 任意のクラス内で 「これは @Binds
で、これは @Provides
で...」ということができない、と言われている気がする。
さあ @InstallIn
がでてきた。さっきは Singleton
として指定したけど、今回はActivityをコンテナとして設定するので、 @InstallIn(ActivityComponent::class)
を付与する。
さっきの Singleton
だったので object 定義でよかったけど、今回はActivityをコンテナとするので、 abstract class
として宣言する。
と、ここまできて このプロジェクト(といかHilt)がjava 8 しかサポートしていないので、もうだめだ。
googleさん... まじどういうことだってばよ...
java のバージョンが新しいとhilt にだめと怒られるし、
java のバージョンを落とすとAndroidStudio(AGP)に怒られる。
まじ鬼畜の所業。
いや、HiltもJava上げろよ。
おん...?
これたぶん、Hiltのビルド処理を実装する前の状態だ。だからJavaを上げてもHiltの機能には影響しなくてビルドが通ってるんだと思う。
hilt が java 8 以降をサポートしていない以上、もうこれ詰んでるじゃん...
というわけで、Hiltが改善されるまでクローズ。
どうやら バージョンを2.53 まであげれば jdk18 が使えるようだ
jdk 18 をインストールして、 v2.53まで上げたら ビルドが通った。
9. 識別子
まずはクラスに依存している実装をインターフェースに依存させるよう既存の実装を書き換えるステップ。
んーちょっとピンときてないけど、 SingletonなオブジェクトとActivityをコンテナとするものを同じプロジェクト内に共存させる場合の実装ってことかな。
で、それをするためには自身でアノテーションぽいもの(修飾子)を定義しないといけない。と。
なるほど、 アノテーションぽいものを Module と 注入する変数との両方に付与することで、どちらを使うかを紐づけているってことかな。
OK。わかった。
10. UI テスト
さあ、一番知りたかったところだ。
何やってるかわけわからんまま、テストランナーを実装させられ、ビルドが通ってやったーと思ってたら
フィールド注入やテストのバインディングの置き換えなど、テストと機能について詳しくは、こちらのドキュメントをご覧ください。
一番知りたいところがこれかよ。ページは↓。
とりあえず、知りたいことがCodelabにないことがわかったので、 11. @EntryPoint アノテーション
は流し読みして終わり。
おわり。