2020年7月16日木曜日

WorkerFactory を使って WorkManager の Worker を生成する

WorkerFactory を使うので Worker のコンストラクタでは任意の引数を取れる。 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 } } } default initializer を削除するための記述を AndroidManifest に追加する。 <manifest ...> <application ...> ... <provider android:name="androidx.work.impl.WorkManagerInitializer" android:authorities="${applicationId}.workmanager-init" tools:ignore="ExportedContentProvider" tools:node="remove" /> </application> </manifest> 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 が用意されている。

参考

0 件のコメント:

コメントを投稿