Нити AsyncTask никогда не умирают
Я использую AsyncTask
для извлечения данных в ответ на нажатие кнопки пользователем. Это хорошо работает и поддерживает взаимодействие интерфейса при извлечении данных, но когда я проверил, что происходит в отладчике Eclipse, я узнал, что каждый раз при создании нового AsyncTask
(что довольно часто, потому что они могут только один раз), создавался новый поток, но никогда не прерывался.
В результате получается большое количество потоков AsyncTask
. Я не уверен, что это проблема на практике или нет, но я бы очень хотел избавиться от этих дополнительных потоков.
Как я могу убить эти потоки?
Ответы
Ответ 1
AsyncTask
управляет пулом потоков, созданным с помощью ThreadPoolExecutor
. Он будет иметь от 5 до 128 потоков. Если имеется более 5 потоков, эти дополнительные потоки будут удерживаться не более 10 секунд перед удалением. (обратите внимание: эти цифры для видимого в настоящее время кода с открытым исходным кодом и отличаются версией Android).
Оставьте только теги AsyncTask
.
Ответ 2
В дополнение к ответу CommonsWare:
В настоящее время я использую Android 2.2, и мое приложение использует не более одной AsyncTask в любое время, но я создаю новую каждые x минут. Сначала появляются новые потоки AsyncTask (новый поток для новой AsyncTask), но после 5 потоков (как упоминается CommonsWare) они просто остаются видимыми в окне отладки и снова используются, когда нужны новые потоки AsyncTask. Они просто остаются там, пока отладчик не отключится.
Ответ 3
Тот же симптом здесь. В моем случае потоки повесили вокруг после того, как я убил Activity, и я надеялся, что приложение полностью закрывается. Проблема частично решена с помощью однопоточного исполнителя:
myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor());
Это заставило поток исчезнуть после завершения его работы.
Ответ 4
Используйте ThreadPoolExecutor.
BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
ThreadPoolExecutor executor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors(), // Initial pool size
Runtime.getRuntime().availableProcessors(), // Max pool size
1, // KEEP_ALIVE_TIME
TimeUnit.SECONDS, // KEEP_ALIVE_TIME_UNIT
workQueue);
Отправьте свою задачу Runnable
с помощью метода execute().
void execute (Runnable command)
Выполняет задание в будущем. Задача может выполняться в новом потоке или в существующем объединенном потоке
Относительно вашего второго запроса:
Как я могу убить эти потоки?
Как только вы закончите со своей работой с помощью ThreadPoolExecutor
, выключите его правильно, как указано в следующем сообщении:
Как правильно закрыть java ExecutorService