今回の前提:
implementation "androidx.work:work-runtime-ktx:2.3.1" api "com.google.dagger:dagger:2.26" kapt "com.google.dagger:dagger-compiler:2.26"
Worker
はWorkManager
によって生成される。デフォルトではContext
とWorkerParameters
が渡されて初期化される。初期化の際、それ以外に必要なオブジェクトを受け取りたいときにはWorkerFactory
を実装してWorkManager
に渡してやる必要がある。独自のWorkerFactory
を実装して使えるようにするには、次のことが必要。
AndroidManifest.xml
でWorkManagerInitializer
を止める。例えば: implemented scheduled worker for record schedule checker · akihito104/nasnen@c3b1d22 · GitHubApplication
クラスにConfiguration.Provider
を実装する。Configuration.Builder
にWorkerFactory
をセットしてbuild()
し、Configuration.Provider.getWorkManagerConfiguration()
から返せるようにする。WorkManager.getInstance(Context)
を使ってWorkManager
を取得する。Context
を受け取らない方はDeprecatedになっている。
戦略はViewModel
の時と大体同じで、Daggerが作ってくれるProvider
のMapをWorkerFactory
に注入して、WorkerFactory.createWorker()
の中でProvider
を取り出して生成したクラスを返してやればよい。ただし、ViewModel
の場合はDIが知っているオブジェクトしか取り扱わないのでDIが初期化までやってくれたのだが、Worker
の場合はWorkerFactory.createWorker()
に渡されるContext
やWorkerParameters
を渡して初期化する必要があるので勝手が違う。
Provider
から出てきたものにContext
とWorkerParameters
を渡して初期化をしたいので、Provider
から出てくるものは具体的なWorker
を作るFactory
である必要がある。例えば:
class HogeWorker( private val repository: HogeRepository, context: Context, param: WorkerParameters ) : CoroutineWorker(context, param) { // 継承するListenableWorkerは何でもいいです // ... class Factory @Inject constructor( private val repository: HogeRepository ) : HogeWorkerFactory.Factory { override fun create( appContext: Context, workerParameters: WorkerParameters ): ListenableWorker = HogeWorker(repository, appContext, workerParameters) } }
よってDaggerからWorkerFactory
に注入するMapは、具体的なWorker
のClassとそのFactory
とを紐づけたもの(例えば、Map<Class<out ListenableWorker>, @JvmSuppressWildcards Provider<Factory>>
)になる。このMapを作るためのBinderは次のような感じ。
@Binds @IntoMap @WorkerKey(HogeWorker::class) fun bindHogeWorker(worker: HogeWorker.Factory): HogeWorkerFactory.Factory