Closed26

Android アプリでの Hilt の使用

どっことどっこと

2. 設定方法

はい、 ビルド が通りません。ほんま。

どっことどっこと

Java関連のエラーが出てたので、脳をタヒらせて以下を書いたらビルドが通った

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_21
        targetCompatibility JavaVersion.VERSION_21
    }
どっことどっこと

3. プロジェクトへの Hilt の追加

今のプロジェクトの構成の説明と、Hiltの導入方法について紹介。
ビルド時にファイルを自動生成するのでルートの build.gradleapp モジュール の 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 が見つからなかった。
ググったら以下が出てきた。すでに削除されている様子。
https://stackoverflow.com/questions/65988186/error-cannot-find-symbol-dagger-hilt-installinvalue-applicationcomponent-c

@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の機能には影響しなくてビルドが通ってるんだと思う。

どっことどっこと

jdk 18 をインストールして、 v2.53まで上げたら ビルドが通った。

どっことどっこと

9. 識別子

まずはクラスに依存している実装をインターフェースに依存させるよう既存の実装を書き換えるステップ。


んーちょっとピンときてないけど、 SingletonなオブジェクトとActivityをコンテナとするものを同じプロジェクト内に共存させる場合の実装ってことかな。

で、それをするためには自身でアノテーションぽいもの(修飾子)を定義しないといけない。と。

どっことどっこと

なるほど、 アノテーションぽいものを Module と 注入する変数との両方に付与することで、どちらを使うかを紐づけているってことかな。

どっことどっこと

10. UI テスト

さあ、一番知りたかったところだ。


何やってるかわけわからんまま、テストランナーを実装させられ、ビルドが通ってやったーと思ってたら

フィールド注入やテストのバインディングの置き換えなど、テストと機能について詳しくは、こちらのドキュメントをご覧ください。

一番知りたいところがこれかよ。ページは↓。
https://developer.android.com/training/dependency-injection/hilt-testing?hl=ja

どっことどっこと

とりあえず、知りたいことがCodelabにないことがわかったので、 11. @EntryPoint アノテーション は流し読みして終わり。

このスクラップは3ヶ月前にクローズされました