WorkerFactory を使うので Worker のコンストラクタでは任意の引数を取れる。
直接 MyWorkerFactory を setWorkerFactory() に渡してもいいが、DelegatingWorkerFactory を使うと複数の Factory から構成させる Factory を作ることができる。
参考
class MyWorker( context: Context, params: WorkerParameters, private val api: MyApi, private val dataStore: DataStore ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { return try { val data = api.getData() dataStore.save(data) Result.success() } catch (e: Exception) { Timber.e(e) Result.failure() } } }
WorkerFactory を用意する。 class MyWorkerFactory( private val api: MyApi, private val dataStore: DataStore ) : WorkerFactory() { override fun createWorker( appContext: Context, workerClassName: String, workerParameters: WorkerParameters ): ListenableWorker? { return if (workerClassName == MyWorker::class.java.name) { MyWorker(appContext, workerParameters, api, dataStore) } else { null } } }
Application で Configuration.Provider を実装し、getWorkManagerConfiguration() で返す Configuration で MyWorkerFactory を指定する。直接 MyWorkerFactory を setWorkerFactory() に渡してもいいが、DelegatingWorkerFactory を使うと複数の Factory から構成させる Factory を作ることができる。
class MyApplication : Application(), Configuration.Provider { ... override fun getWorkManagerConfiguration(): Configuration { val api = appComponent.api() val dataStore = appComponent.dataStore() val delegatingWorkerFactory = DelegatingWorkerFactory().apply { addFactory(MyWorkerFactory(api, dataStore)) } return Configuration.Builder() .setWorkerFactory(delegatingWorkerFactory) .build() } }
Subcomponent を使えば WorkerFactory と Worker 両方 Dagger に生成させることもできるし、なんなら Hilt には HiltWorkerFactoryが用意されている。 参考
- Android Developers: Custom WorkManager Configuration and Initialization
- WorkerFactory
- DelegatingWorkerFactory