Выполнить AsyncTask несколько раз

В моей работе я использую класс, который простирается от AsyncTask и параметр, являющийся экземпляром этой AsyncTask. Когда я вызываю mInstanceOfAT.execute("") все в порядке. Но приложение падает, когда я нажимаю кнопку обновления, которая вызывает снова AsyncTask (в случае, если сетевое задание не работает). В результате возникает исключение, в котором говорится:

Невозможно выполнить задачу: задача уже выполнена (задача может быть выполнена только один раз)

Я попытался вызвать cancel (true) для экземпляра Asyctask, но он тоже не работает. Единственное решение – создать новые экземпляры Asyntask. Правильно ли это?

Благодарю.

AsyncTask могут использоваться только один раз.

Вместо этого просто вызовите свою задачу, как new MyAsyncTask().execute("");

Из документов API AsyncTask:

Правила потоковой передачи

Для правильного функционирования этого класса необходимо соблюдать несколько правил потоковой передачи:

  • Экземпляр задачи должен быть создан в потоке пользовательского интерфейса.
  • Execute (Params …) должен быть вызван в потоке пользовательского интерфейса.
  • Не вызывайте onPreExecute (), onPostExecute (Result), doInBackground (Params …), onProgressUpdate (Прогресс …) вручную.
  • Задача может быть выполнена только один раз (исключение будет выбрано при попытке выполнить второе выполнение).

Причины для экземпляров ASyncTask для Fire-and-forget подробно описаны в ответе Стива Прентиса. Однако, хотя вы ограничены тем, сколько раз вы выполняете ASyncTask, вы можете делать то, что вам нравится, пока поток работает. ,

Поместите исполняемый код внутри цикла в doInBackground () и используйте одновременную блокировку для запуска каждого выполнения. Вы можете получить результаты, используя publishProgress () / onProgressUpdate () .

Пример:

 class GetDataFromServerTask extends AsyncTask<Input, Result, Void> { private final ReentrantLock lock = new ReentrantLock(); private final Condition tryAgain = lock.newCondition(); private volatile boolean finished = false; @Override protected Void doInBackground(Input... params) { lock.lockInterruptibly(); do { // This is the bulk of our task, request the data, and put in "result" Result result = .... // Return it to the activity thread using publishProgress() publishProgress(result); // At the end, we acquire a lock that will delay // the next execution until runAgain() is called.. tryAgain.await(); } while(!finished); lock.unlock(); } @Override protected void onProgressUpdate(Result... result) { // Treat this like onPostExecute(), do something with result // This is an example... if (result != whatWeWant && userWantsToTryAgain()) { runAgain(); } } public void runAgain() { // Call this to request data from the server again tryAgain.signal(); } public void terminateTask() { // The task will only finish when we call this method finished = true; lock.unlock(); } @Override protected void onCancelled() { // Make sure we clean up if the task is killed terminateTask(); } } 

Конечно, это немного сложнее, чем традиционное использование ASyncTask, и вы отказываетесь от использования publishProgress () для фактической отчетности о ходе работы. Но если память беспокоит вас, тогда этот подход обеспечит сохранение только одной ASyncTask в куче во время выполнения.

Я поставил статические задачи вращения, которые затем помогли мне прикрепить, отсоединить и снова подключить их к потокам пользовательского интерфейса при изменениях вращения. Но чтобы вернуться к вашему вопросу, я создаю флаг, чтобы увидеть, работает ли поток. Когда вы хотите перезапустить поток, я проверяю, запущена ли задача вращения, если я хочу поджечь предупреждение. Если это не так, я делаю его нулевым, а затем создаю новый, который будет работать вокруг ошибки, которую вы видите. Кроме того, после успешного завершения я удаляю завершенную задачу, связанную с ротацией, так что она готова снова идти.

Я была такая же проблема. В моем случае у меня есть задача, которую я хочу сделать в onCreate() и в onResume( ). Поэтому я сделал статический Asynctask и получаю экземпляр из него. Теперь у нас все та же проблема.

Так что я сделал в onPostExecute ():

 instance = null; 

Помня, что я проверяю статический метод getInstance, что мой экземпляр не является нулевым, иначе я его создаю:

 if (instance == null){ instance = new Task(); } return instance; 

Метод postExecute очистит экземпляр и восстановит его. Конечно, это можно сделать вне класса.

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

Каждый раз, когда вам нужно его использовать, вы должны указать:

 // Any time if you need to call her final FirmwareDownload fDownload = new FirmwareDownload(); fDownload.execute("your parameter"); static class FirmwareDownload extends AsyncTask<String, String, String> { } 
Intereting Posts
Отправка запроса POST с помощью JSONArray с использованием Volley Тестирование устройств Android – проблемы с разрешением и проверкой Как обращаться с кнопкой возврата в Search View в android Запрос на разрешение местоположения при отсутствии мониторинга в фоновом режиме? Как программно принудительно запустить полный перезапуск приложения? Например, убить, а затем начать Реагирует ли исходный кеш удаленных изображений? Java.lang.RuntimeException: Невозможно создать экземпляр активности ComponentInfo / ClassNotFoundException Logcat «рассылается спамом», что приводит к «слишком большому результату обработки», Планирование автономных задач, которые должны выполняться при подключении пользователя к Интернету Извращенные андроидные фильтры Cordova Конечные точки Google Cloud: verifyToken: длина подписи неверна Как написать приложение для Android для чтения / записи sysfs? Усечение видео с помощью MediaCodec Android: как создавать разные «экраны» и навигацию между ними с помощью touch-and-drag? Разлагают ли фрагменты жирную деятельность?