Как узнать ID задачи в WorkManager?

Здравствуйте. 

1) Как можно получить ID задачи сразу после её запуска? Я уже перепробовал множество решений, но они мне, похоже, не подходят. Например, почему при вызове:

<pre><code>WorkManager.getInstance(this).enqueueUniquePeriodicWork("TagWorker",
            ExistingPeriodicWorkPolicy.KEEP,myWorkRequest)</code></pre>

и затем попытке получить ID с помощью:

<pre><code>val workInfo = WorkManager.getInstance(this).getWorkInfoByIdLiveData(myWorkRequest.id)
        println(workInfo.value?.id)</code></pre>

возвращается Null?

Я вызываю этот код в Activity по нажатию кнопки:

<pre><code>val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
        val myWorkRequest = PeriodicWorkRequest.Builder(Worker::class.java, 15, TimeUnit.MINUTES)
            .setConstraints(constraints)
            .addTag("WorkerTag")
            .setInputData(data.build())
            .build()
        WorkManager.getInstance(this).enqueueUniquePeriodicWork("TagWorker",
            ExistingPeriodicWorkPolicy.KEEP,myWorkRequest)</code></pre>

А вот код самого Worker'а:

<pre><code>class Worker(context: Context, workerParameter: WorkerParameters): Worker(context, workerParameter){
 override fun doWork(): Result {
            Log.d("doWork", "doWork: Success function called")
 return Result.success()
}
}</code></pre>

2) Существуют ли строки о завершенных задачах в внутренней базе WorkManager, и должны ли они удаляться? 

Скажем, если использовать:

<pre><code>WorkManager.getInstance(this).cancelAllWorkByTag("tag")
            WorkManager.getInstance(this).cancelAllWork()</code></pre>
  • 20 ноября 2024 г. 21:23
Ответы на вопрос 2
Здравствуйте!

### 1) Как получить ID задачи сразу после её запуска

Когда вы создаете и ставите в очередь задачу в WorkManager, на самом деле ID задачи еще не доступен до тех пор, пока WorkManager не обработает запрос на выполнение. Это может занять некоторое время. Поэтому, когда вы пытаетесь получить информацию о задаче сразу после её enqueue, это возвращает null, потому что задача еще не была полностью создана в системе.

Чтобы получить ID задачи, вам нужно использовать `WorkManager` в сочетании с `LiveData`. Вместо того чтобы сразу пытаться получить `workInfo`, вы можете использовать `WorkManager.getWorkInfoByIdLiveData(myWorkRequest.id)` и подписаться на изменения, чтобы быть уведомленным, когда информация о задаче будет доступна.

Пример кода:

```kotlin
val myWorkRequest = PeriodicWorkRequest.Builder(Worker::class.java, 15, TimeUnit.MINUTES)
    .setConstraints(constraints)
    .addTag("WorkerTag")
    .setInputData(data.build())
    .build()

// Ставим задачу в очередь
WorkManager.getInstance(this).enqueueUniquePeriodicWork("TagWorker", ExistingPeriodicWorkPolicy.KEEP, myWorkRequest)

// Подписываемся на LiveData для получения информации о состоянии
WorkManager.getInstance(this).getWorkInfoByIdLiveData(myWorkRequest.id).observe(this, Observer { workInfo ->
    if (workInfo != null) {
        // Теперь workInfo доступен
        println("Task ID: ${workInfo.id}")
    }
})
```

Обратите внимание, что использование `observe` требует контекста, который будет оставаться активным до тех пор, пока `LiveData` или `Activity` не будут уничтожены. Поэтому лучше использовать `this` из `Activity` или `Fragment`.

### 2) Позволяет ли WorkManager хранить завершенные задачи

Да, WorkManager хранит информацию о завершенных задачах и состоянии работ в своей внутренней базе данных. Когда вы используете методы, такие как `cancelAllWorkByTag("tag")` или `cancelAllWork()`, они отменяют текущие и ожидающие задачи с указанным тегом или все задачи, но завершенные задачи остаются в базе данных.

У WorkManager есть механизм для автоматической очистки устаревших записей, если они больше не нужны, но существуют некоторые временные рамки, которые варьируются от версии к версии. По умолчанию задачи, выполненные более 10 дней назад, могут быть автоматически очищены, но это может зависеть от конкретной реализации WorkManager и различных настроек.

Таким образом, если вам необходимо очистить систему от завершенных задач, то необходимо управлять таким состоянием самостоятельно, так как по умолчанию они не удаляются мгновенно.
Можно получить при нажатии на кнопку: 
WorkManager.getInstance(this).getWorkInfoByIdLiveData(myWorkRequest.id).observe(this,
            Observer{                
                println("it.id: ${it!!.id}")
            })


Но как сразу при первом запуске получить ID из class Worker, вернуть с Result.success?
Похожие вопросы