В своей деятельности я использую класс, расширяющий AsyncTask, и параметр, являющийся экземпляром этой AsyncTask. Когда звоню, mInstanceOfAT.execute("")
все нормально. Но приложение вылетает, когда я нажимаю кнопку обновления, которая снова вызывает AsyncTask (в случае, если сетевое задание не работает). Причина тогда появляется исключение, которое говорит
Невозможно выполнить задачу: задача уже выполнена (задача может быть выполнена только один раз)
Я попытался вызвать cancel (true) для экземпляра Asyctask, но он тоже не работает. Единственное решение на данный момент - создание новых экземпляров Asyntask. Это правильный путь?
Спасибо.
источник
Причины запускать и забывать экземпляры ASyncTask довольно подробно описаны в ответе Стива Прентиса. Однако, хотя вы ограничены тем, сколько раз вы выполняете ASyncTask, вы можете делать то, что вам нравится, пока поток работает. ,
Поместите исполняемый код в цикл внутри doInBackground () и используйте параллельную блокировку для запуска каждого выполнения. Вы можете получить результаты, используя publishProgress () / onProgressUpdate () .
Пример:
Конечно, это немного сложнее, чем традиционное использование ASyncTask, и вы отказываетесь от использования publishProgress () для фактического отчета о ходе выполнения. Но если вас беспокоит память, то этот подход гарантирует, что во время выполнения в куче останется только одна ASyncTask.
источник
IllegalMonitorStateException
вrunAgain
(вызываетсяonProgressUpdate
) увидеть этот ответ: stackoverflow.com/a/42646476/2711811 . Это предполагает (и сработало для меня), чтоsignal()
нужно окружитьlock
/unlock
. Возможно, это связано со временемpublishProgress
звонкаonProgressUpdate
.Я была такая же проблема. В моем случае у меня есть задача, которую я хочу выполнять
onCreate()
вonResume(
). Итак, я сделал свой Asynctask статическим и получил от него экземпляр. Теперь у нас все еще та же проблема.Итак, что я сделал в onPostExecute (), так это:
Помня, что я проверяю статический метод getInstance, что мой экземпляр не равен нулю, иначе я создаю его:
Метод в postExecute очистит экземпляр и создаст его заново. Конечно, это можно делать вне класса.
источник
Я сделал свои задачи вращения статическими, что затем помогло мне присоединять, отсоединять и повторно прикреплять их к потокам пользовательского интерфейса при изменении вращения. Но возвращаясь к вашему вопросу, я создаю флаг, чтобы увидеть, запущен ли поток. Когда вы хотите перезапустить поток, я проверяю, запущена ли задача вращения, если это предупреждение. Если это не так, я делаю его нулевым, а затем создаю новый, который будет работать с ошибкой, которую вы видите. Кроме того, после успешного завершения я обнуляю завершенную задачу с учетом ротации, чтобы она снова была готова к работе.
источник
Да, это правда, в документе говорится, что может быть выполнена только одна Asyntask.
Каждый раз, когда вам нужно его использовать, вы должны указать:
источник