Наблюдатель рабочего состояния всегда в очереди

Я пытаюсь наблюдать за своими 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
3
0
1 834
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Для вашего периодического запроса на работу вы должны увидеть

ENQUEUED - RUNNING - ENQUEUED

где последний ENQUEUED - это состояние следующего запроса на работу.

Вы можете на короткое время получить УСПЕШНО между ЗАПУСКОМ и ЗАВЕРШЕНИЕМ, но я никогда этого не видел.

Для разового запроса на работу вы видите

ENQUEUED - RUNNING - SUCCEEDED

или все, что вы вернете в doWork ().

(Android 8.1 API 27, 1.0.0-alpha04)

Означает ли это, что я никогда не смогу передать data от рабочего к пользовательскому интерфейсу при использовании периодического запроса? потому что он говорит, что data установлен, когда workstatus.state - это SUCCEEDED

Kakashi 23.07.2018 17:48

Результат doWork () в первую очередь предназначен для WorkManager. Например, если у вас есть одноразовый запрос, когда рабочий возвращает RETRY, WorkManager ставит в очередь другой запрос, несмотря на его одноразовость. Если вы хотите передать какие-либо данные / информацию от рабочего к выпускающему действию, вам нужно подумать о других механизмах, которые могут это сделать.

nst0022 23.07.2018 20:30

вот что я имел в виду developer.android.com/reference/androidx/work/…. там написано This method is invoked after doWork() returns Worker.WorkerResult.SUCCESS and there are chained jobs available.

Kakashi 23.07.2018 20:55

Хорошо, теперь я знаю, что вы имеете в виду под «данными»: передача объекта данных от (здесь периодического) workerA к связанному workerB. Опять же, результат первого запуска workerA может быть кратко отражен в его состоянии, но это состояние будет перезаписано вторым запуском workerA, помещенным в очередь. Тот факт, что вы не видите УСПЕХ, не обязательно означает, что объект Data не передается в workerB. Это вам следует просто проверить. Если это не сработает, значит, это ошибка, и о ней следует сообщить.

nst0022 24.07.2018 05:15

Приведенный выше ответ правильный. Для PeriodicWork вы должны увидеть:

ENQUEUED -> RUNNING -> ENQUEUED

Однако в alpha04 есть ошибка, из-за которой PeriodicWork не запускается на API> = 23. Это будет исправлено в alpha05. Для получения дополнительной информации взгляните на https://issuetracker.google.com/issues/111195153.

ВАЖНО: По состоянию на пару дней назад: alpha05 отправлен. Это ошибка фиксированный.

моя targetSdkVersion - 26. Я также столкнулся с проблемой, из-за которой worker.doWork() внезапно перестает работать по какой-то причине с периодической работой или OneTimeWork (она запускалась раньше), если я не удалю приложение. Мне даже нужно написать еще один скрипт с asynctask, чтобы убедиться, что я не сделал ничего плохого со своими кодами, и оказалось, что с моими кодами, использующими asyncTask, проблем не было. Спасибо, Рахул

Kakashi 24.07.2018 11:46

один быстрый простой вопрос. скажем, у меня есть сценарий select * from bla bla в doWork(), когда этот сценарий выполняется? в состоянии ENQUEUED или в состоянии RUNNING?

Kakashi 25.07.2018 20:54

Это для тех, у кого возникают проблемы с получением выходных данных в результате периодической работы. Это больше похоже на взлом. В вашем Worker просто определите статические изменяемые Live Data. В том месте, где вы наблюдаете за состоянием своей работы, наблюдайте за этими данными в реальном времени, когда ваше состояние переходит в состояние «РАБОТАЕТ».

Вот шаблон:

  1. Фактический работник:
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();
    }
}

  1. Ваша деятельность, при которой соблюдается информация об этом работнике:
//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
                           }
                      }
                   );
             }
          }
       }
   }
);

Таким образом, вы можете наблюдать за своими результатами, когда работа находится в рабочем состоянии, прежде чем она снова будет переведена в очередь.

Другие вопросы по теме