#android #kotlin-coroutines #android-workmanager #dagger-hilt
Вопрос:
Я пытаюсь использовать WorkManager для периодического получения количества уведомлений из API, проблема в том, что я использую hilt для внедрения зависимостей, поэтому я не могу ввести в свой репозиторий «@Inject», даже если я использовал @AndroidEnteryPoint. И как я могу наблюдать за полученными данными внутри функции «DoWork».
class NotificationsCountWorker
(
val context: Context,
workerParams: WorkerParameters) :
CoroutineWorker(context, workerParams) {
@Inject lateinit var repo: RepositoryImpl
override suspend fun doWork(): Result {
Log.d(TAG, "doWork")
//subscribeObserver()
return try {
withContext(Dispatchers.IO) {
try {
Log.d(TAG, "inside with context")
repo.notificationsCount().onEach {
Log.d(TAG, "item; $it")
}.launchIn(this)
Log.d(TAG, "notif count ")
Result.success()
} catch (e: Exception){
Log.d(TAG, "exception ${e.message}")
Result.failure()
}
}
}catch (e:Exception){
Log.d(TAG, "exception ${e.message}")
Result.failure()
}
}
companion object {
private const val TAG = "NotificationsWorkManger"
const val NOTIFICATIONS_COUNT_WORK_MANGER_ID = "automatic_notifications_count_manger"
fun reminder() {
val periodicRefreshRequest = PeriodicWorkRequest.Builder(
NotificationsCountWorker::class.java, // Your worker class
15, // repeating interval
TimeUnit.MINUTES
)
val periodicWorkRequest: PeriodicWorkRequest = periodicRefreshRequest
.build()
WorkManager.getInstance(getApplication()).enqueueUniquePeriodicWork(
NOTIFICATIONS_COUNT_WORK_MANGER_ID,
ExistingPeriodicWorkPolicy.REPLACE,
periodicWorkRequest
)
}
}
}
Комментарии:
1. Вы используете конкретную интеграцию между Hilt и WorkManager ?
2. Я не внедряю менеджер работ, я пытаюсь только внедрить в него репозиторий, но даже когда я следовал определенной интеграции, это ничего не изменило
3. Как вы думаете, что делает интеграция между Hilt и WorkManager, кроме как позволяет вам внедрить репозиторий в вашего работника? Это именно тот пример, который приведен в документах.
4. да, я сделал это после вашего первого сообщения, и я следил за документацией, но это все та же проблема, которая поздно, но еще не инициирована
Ответ №1:
Вам нужно внедрить свои зависимости через конструктор. Для того, чтобы сделать инъекцию Рабочему с рукояткой, вам нужно сделать следующее.
Во-первых, аннотируйте своего рабочего, его конструктор и аргументы конструктора как таковые:
@HiltWorker
class MyWorker @AssistedInject constructor(
@Assisted context: Context,
@Assisted workerParameters: WorkerParameters,
private val repository: Repository
) : CoroutineWorker(context, workerParameters)
Вы должны только аннотировать context
и workerParameters
как @Assisted
. Все остальные ваши зависимости разрешаются с помощью Hilt, они должны быть установлены SingletonComponent
или не иметь области видимости.
Затем внедрите HiltWorkerFactory
в свой основной Application
производный класс и сделайте так, чтобы этот класс реализовывал Configuration.Provider
интерфейс следующим образом:
@HiltAndroidApp
class MainApplication : Application(), Configuration.Provider {
@Inject
lateinit var workerFactory: HiltWorkerFactory
override fun getWorkManagerConfiguration() =
Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
}
Последний шаг — отключить инициализацию WorkManager по умолчанию. Для этого вставьте эти строки в свой AndroidManifest.xml
, если вы используете WorkManager версии 2.6.0-alpha01 или выше:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- If you are using androidx.startup to initialize other components -->
<meta-data
android:name="androidx.work.impl.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
или
<!-- If you want to disable android.startup completely. -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove">
</provider>
Если вы используете более старые версии, вам следует добавить это:
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
Комментарии:
1. Привет, спасибо, я ценю ваш ответ, это то, что я ищу.