はじめに
Daggerのことググってもとりあえず動かしたいくらいの解説があまりなかったので、とりあえず動く物を。
あと、インジェクションするオブジェクトにactivityを引数として渡さないといけない時の方法で詰まったのでそれも書きます。
ソースはこちら
Daggerについて
ググってください
Daggerの下準備
Gradle(app)に下記追加
// Dagger
implementation "com.google.dagger:dagger:$dagger_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
implementation "com.google.dagger:dagger-android-support:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
kaptTest "com.google.dagger:dagger-compiler:$dagger_version"
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
Syncして完了
Injectするオブジェクトを作成
class Thermometer @Inject constructor(val activity: SecondActivity) {
fun getTemperature(): String {
return activity.getString(R.string.temperature)
}
}
@Inject constructor
が肝っぽい
string.xmlにtemperatureを追加
<string name="temperature">30℃</string>
Componentを作成
@Component
interface Room {
@Component.Builder
interface Builder {
@BindsInstance
fun application(activity: SecondActivity): Builder
fun build(): Room
}
fun inject(activity: SecondActivity)
}
インジェクトされる側を作成
class SecondActivity : AppCompatActivity() {
lateinit var binding: ActivitySecondBinding
private val viewModel = SecondViewModel()
private lateinit var room: Room
@Inject
lateinit var thermometer: Thermometer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_second)
room = DaggerRoom.builder().application(this).build()
room.inject(this)
viewModel.textView = thermometer.getTemperature()
binding.textView.text = viewModel.textView
}
}
完成
こんな感じでstring.xmlの内容が表示されてると思います。
activityの引き渡し
Componentに
@Component.Builder
interface Builder {
@BindsInstance
fun application(activity: SecondActivity): Builder
fun build(): Room
}
があるが、Daggerでactivityを引数として入れる時に必要になる。
これがない場合、
SecondActivity cannot be provided without an @Inject constructor or from an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
というエラーが発生する。
基本的に、Daggerでインジェクションするオブジェクトの引数には@Inject
等で値を入力されたものしか渡せないらしい。。。
####ついでに
activityが必要ないタイプの例もMainActivityに書いてある。
AndroidManifestの
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
を変更すれば表示が切り替わる
おわり