AsyncTask, RejectedExecutionException и Task Limit - PullRequest
15 голосов
/ 22 марта 2010

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

Я получаю исключение RejectedExecution в своем коде.Я вспоминаю, что где-то читал, что существует ограничение на количество задач, которые AsyncTask может иметь в своей очереди за раз, возможно, я попал в это.Этот бар был поднят?

Есть ли способ увеличить этот лимит?Безопасно ли просто игнорировать это исключение? (Имея пустой блок catch(RejectedException e){}?)

Я выполняю этот код на эмуляторе Android 1.6 и уровень API в моем коде (minSDKVersion равен 3).[РЕДАКТИРОВАТЬ: Добавлена ​​информация об уровне SDK и API]

Ответы [ 5 ]

17 голосов
/ 22 марта 2010

Я помню, что читал где-то, что там это ограничение на количество задач, которые AsyncTask может иметь в своей очереди на время, я мог бы ударить это. Было этот бар снят?

AsyncTask в настоящее время, по-видимому, поддерживает 10 потоков и глубину рабочей очереди 10. Теоретически, это будет просто поддерживать 20 элементов ... если ничего не использует AsyncTask.

Есть ли способ увеличить этот лимит?

Соберите исходный код, измените его, поместите в свой собственный пакет и используйте его. Я сделал это с моим AsyncTaskEx, хотя он основан на источнике Android 1.5.

Безопасно ли просто игнорировать это исключение?

Ваша работа не будет поставлена ​​в очередь на исполнение. Насколько это безопасно, решать вам. Мне не известно о каких-либо других воздействиях на инфраструктуру AsyncTask.

7 голосов
/ 04 мая 2011

Я сделал то же самое в приложении.

Одновременный запуск 20 параллельных потоков для загрузки миниатюр с сервера и передачи их в адаптер данных для меня не очень хорошая идея. Все эти темы будут просто переплетаться и мешать друг другу.

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

2 голосов
/ 25 июня 2014

Проблема в том, что число ожидающих AsyncTasks для AsyncTask.THREAD_POOL_EXECUTOR равно 128. Как только очередь заполнена, новые AsyncTasks не могут быть поставлены в очередь.

Из исходного кода AsyncTask:

private static final BlockingQueue<Runnable> sPoolWorkQueue =
        new LinkedBlockingQueue<Runnable>(128);

По моему мнению, ограничение не имеет абсолютно никакого смысла, а AsyncTask.SERIAL_EXECUTOR имеет неограниченную очередь.

2 голосов
/ 14 мая 2012

Вы можете использовать последовательный исполнитель с AsyncTask.executeOnExecutor, чтобы сериализовать ваши задачи, но это ограничит задачу только одной параллельной задачей за один раз. Может быть хорошо, когда получаешь миниатюры:

myAsyncTask.executeOnExecutor (MyAsyncTask.SERIAL_EXECUTOR, [params]);

1 голос
/ 04 мая 2011

«Безопасно» игнорировать - вам нужно убедиться, что любое уведомление, которое вы планировали сделать в пост-выполнении, будет сделано здесь, когда вы поймете ошибку - иначе вы можете оставить что-то зависшим, если ваш другой кодделает предположения о получении ответа от этой задачи.

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