AsyncTask, исключение RejectedExecutionException и Ограничение задачи

StackOverflow https://stackoverflow.com/questions/2492909

Вопрос

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

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

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

Я запускаю этот код на эмуляторе Android 1.6 и уровне API в моем коде (minSdkVersion равен 3).[ПРАВИТЬ:Добавлена информация об уровне SDK и API]

Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

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

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

myAsyncTask.executeOnExecutor(MyAsyncTask.SERIAL_EXECUTOR, [параметры] );

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

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

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

На мой взгляд, это ограничение вообще не имеет абсолютно никакого смысла, и AsyncTask.SERIAL_EXECUTOR имеет неограниченную очередь.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top