Наблюдатель за рабочим статусом всегда в исправном состоянии
Я пытаюсь наблюдать за моим workers
но они всегда в queued
состояние или когда-нибудь это RUNNING
но никогда SUCCEED
или же FAILED
,
является workStatus.state
от возвращения в doWork()
или это другое?
это мой рабочий скрипт:
package com.mockie.daikokuten.sync.workers
import androidx.work.Worker
class TestWorker:Worker()
{
override fun doWork():Worker.Result
{
return Worker.Result.SUCCESS
}
}
это скрипт для наблюдения за рабочими:
val test = PeriodicWorkRequest.Builder(
TestWorker::class.java,
PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS,
TimeUnit.MILLISECONDS)
.addTag("test_worker")
.build()
WorkManager.getInstance()?.enqueueUniquePeriodicWork("test_worker", ExistingPeriodicWorkPolicy.KEEP, test)
WorkManager.getInstance()!!.getStatusesByTag("test_worker")
.observe(this, Observer { workStatus ->
if (workStatus != null)
{
for(ws in workStatus)
{
Log.d(":dump2 id ", ws.id.toString())
Log.d(":dump2 tag", ws.tags.toString())
Log.d(":dump2 state", ws.state.toString())
}
}
})
это результат в Logcat:
07-23 17:12:30.901 29740-29740/com.mockie.daikokuten D/:dump2 id: 5c6297f7-11d8-4f2f-a327-773672a7435c
07-23 17:12:30.901 29740-29740/com.mockie.daikokuten D/:dump2 tag: [test_worker, com.mockie.daikokuten.sync.workers.TestWorker]
07-23 17:12:30.901 29740-29740/com.mockie.daikokuten D/:dump2 state: ENQUEUED
4 ответа
Для вашего периодического запроса на работу вы должны увидеть
ENQUEUED - RUNNING - ENQUEUED
где последний ENQUEUED - это состояние следующего рабочего запроса.
Вы можете очень кратко добиться успеха между бегом и бегом, но я никогда не видел этого.
Для разового запроса на работу вы видите
ENQUEUED - RUNNING - SUCCEEDED
или что вы возвращаете в doWork ().
(Android 8.1 API 27, 1.0.0-alpha04)
Это для тех, у кого возникают проблемы с получением выходных данных от периодической работы. Это больше похоже на взлом. В вашем Worker просто определите статические изменяемые живые данные. В месте, где вы наблюдаете состояние своей работы, наблюдайте эти данные в реальном времени, когда ваше состояние превращается в "РАБОТА".
Вот шаблон:
- Фактический Работник:
public class SomeWorker extends Worker{
//This live data can be of any type. I'm setting Boolean
Public static MutableLiveData<Boolean> outputObservable = new MutableLiveData();
private boolean output_boolean;
try{
//Do you work here post your result to the live data
output_boolean = SomeTaskThatReturnsABoolean();
outputObservable.postValue(output_boolean);
return Result.Success();
}catch(Exception e){
e.printStackTrace();
outputObservable.postValue(!output_boolean);
return Result.Failure();
}
}
- Ваша деятельность, которая отслеживает информацию этого работника:
//In YourActivity class inside OnCreate
mWorkManager.getWorkInfoForUniqueWorkLiveData(YOUR_TAG).observe (this,
new Observer<List<WorkInfo>>(){
@Override
public void onChanged(@Nullable List<WorkInfo> workInfos) {
if(workInfos!=null && (!(workInfos.isEmpty()))) {
WorkInfo info = workInfos.get(0);
switch(info.getState()){
case ENQUEUED:
break;
case RUNNING:
SomeWorker.outputObservable.observe(YourActivity.this,
new Observer<Boolean>(){
@Override
public void onChanged(@Nullable Boolean aBoolean) {
//EDIT: Remove the observer of the worker otherwise
//before execution of your below code, the observation might switch
mWorkManager.getWorkInfoForUniqueWorkLiveData(YOUR_TAG).removeObservers(YourActivity.this);
if(aBoolean)
//Do whatever you have to if it's true
else
//Do whatever you have to if it's false
}
}
);
}
}
}
}
);
Таким образом, вы можете наблюдать за своими результатами, когда состояние работы находится в процессе выполнения, прежде чем оно будет переведено обратно в очередь.
Приведенный выше ответ является правильным. Для PeriodicWork вы должны увидеть:
ENQUEUED -> RUNNING -> ENQUEUED
Тем не менее, есть ошибка в alpha04
что приводит к PeriodicWork
не работать на API >= 23. Это будет исправлено в alpha05
, Для получения дополнительной информации посмотрите на https://issuetracker.google.com/issues/111195153.
ВАЖНО: По состоянию на пару дней назад: alpha05
отправлен. Эта ошибка исправлена.
Как уже говорили другие, это действительно никогда не достигнетSUCCEEDED
состояние, поэтому вы никогда не сможете наблюдать какое бы значение вы ни возвращали в своем Result.success(yourData).
Но надежда еще не потеряна! Фактически вы можете наблюдать данные вPeriodicWorkRequest
s без каких-либо хаков, таких как настройка статических наблюдаемых или запись/чтение данных в/из общих настроек или локальной базы данных.
В doWork мы устанавливаем данные через setProgress и добавляем неблокирующую задержку с помощью функции задержки() Coroutine перед возвратом результата:
override suspend fun doWork(): Result {
// do long running work, like waiting for the result of an async api call
val outputData: Data = Data.Builder()
.putString("asyncString", asyncString)
.build()
setProgress(outputData)
delay(1000)
Result.success()
}
Затем вы можете наблюдать за LiveData (или потоком Kotlin), полученным с помощью getWorkInfoByIdLiveData, и читать данные, которые вы установили в setProgress WorkInfo, с помощью getProgress()WorkInfo:
val workRequest = PeriodicWorkRequestBuilder<MyWorker>(1, TimeUnit.HOURS)
.setInputData(workerData)
.build()
WorkManager.getInstance(context).enqueue(workRequest)
val workInfo = WorkManager.getInstance(context).getWorkInfoByIdLiveData(workRequest.id).asFlow()
scope.launch {
updateWorkInfo.collect { workInfo ->
workInfo.progress.getString("asyncString", "")
}
}
Задержка в 1 секунду, которую мы установили в doWork() перед возвратом Result.success(), необходима, поскольку при вызове Result.success() работа немедленно завершается, и ее состояние становитсяENQUEUED
; у вас не будет достаточно времени, чтобы наблюдать за текущей работой.
Подробнее:https://developer.android.com/guide/background/persistent/how-to/observe .