ViewModelでAssistedInjectを使う
Dagger 2.31より、AssistedInjectのサポートが入りました。このAssistedInjectをViewModelで使用する方法です。
追記: この方法には問題があります。SavedStateHandleを使うようにしましょう。
画面の引数などをDaggerのInjectと組み合わせて、ViewModelのコンストラクタに渡したい場合があったりします。
こういったケースではAssistedInjectを使うことで可能になります。
(他には SavedStateHandle を使う方法もあります。)
build.gradle
2.31のHiltを使っていきます。
ViewModel
以下のようなコンストラクタを持つViewModelを例にします。
1つ目は通常のDaggerモジュールなどに定義されたオブジェクトで、2つ目で SavedStateHandle
も受け取るようにします。最後に画面から渡したい引数になります。
今回は SavedStateHandle
も使ってますが、不要なら無くても大丈夫です。
AssistedFactory
画面から渡したいものを AssistedFactory として定義します。
画面からコンストラクタに渡したいものを引数にして、Injectしたいクラスが戻り値になってるメソッドを定義したinterfaceを作ります。
interfaceには @AssistedFactory
のアノテーションを追加します。
ViewModelFactory
次にViewModelFactoryを定義しておきます。
今回は SavedStateHandle
も使ってるので AbstractSavedStateViewModelFactory
を使っています。もし不要なら ViewModelProvider.Factory
も使えます。
ViewModelのインスタンスは AssistedFactory のメソッドから作成して返します。
AssistedInject
コンストラクタを AssistedInject の設定をします。
AssistedInjectしたい引数に @Assisted
を追加します。
ただし、通常のモジュールからInjectするものは無くて大丈夫です。
コンストラクタには @Inject
の代わりに @AssistedInject
を追加します。
画面から値を渡す
最後に画面から値を渡すようにします。
先程作った AssistedFactory をInjectするようにして、それをViewModelFactoryで使用する感じになります。
ちょっとややこしそうに見えますが、一度やってみるとそこまで難しくはないと思います。
注意点
AssistedFactory と AssistedInject のパラメーターの引数の順番は一致している必要があります。
AssistedInject においては引数の順番が重要になってきます。これは意図しないバグに繋がる可能性もあるので注意してください。