Pull to refresh

Comments 17

А вообще грузите-ка картинки лучше с помощью этого, а не плодите своих костылей.
эта библиотека <наверно> здорово помогает в загрузке и кешировании картинок, но в статье картинки — только пример.
загрузка картинок — очень типовая операция в андроиде и, конечно, уже есть тысячи библиотек для загрузки картинок, но в статье помимо примеров с картинкой еще много чего про фоновые процессы :)
Я понимаю, просто озвучил 1002 способ =)
После таких статей всегда думаю «как же хорошо что в iOS есть GCD»
Минусуют из зависти, очевидно.
Минусуют наверное из-за того, что ждут конкретного примера преимуществ
> работающие [...] AsyncTask [...] не позволят сборщику мусора удалить экземпляр нашей Activity
Можно держать пул AsyncTask'ов и в onStop останавливать их.
Для конкретно этой задачи — загрузки картинок — мне в своей практике обычно хватало расширенного AsyncTask'a на пару десятков строк.
Но в любом случае, интересное сравнение альтернатив.
>Начиная с Android HONEYCOMB по умолчанию для всех background операций экземпляров AsyncTask отводится только один поток.

Не совсем точно, так как начиная со следующей версии количество увеличено до 128
Вы, скорее всего, говорите о максимальном размере пула у ThreadPoolExecutor, экземпляр которого использует AsyncTask. Однако, запустить задачу в этом экзекуторе можно только методом task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, <остальные параметры>);
Если посмотреть исходники AsyncTask любой из последних версий android (например, тут grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/os/AsyncTask.java), то можно заметить, что коммандой AsyncTask#execute(…) задача будет передана не в ThreadPoolExecutor, а в дефолтный SerialExecutor с одним потоком.
Надеюсь мой комментарий будет полезен.
Разумеется, один AsyncTask = один поток, но:
По вашей же ссылке важный участок кода в классе дефолтного SerialExecutor тут:
protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }

Потому количество потоков AsyncTask (в версии API по указанной вами ссылке) будет ограничено значением:
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;

В API 19 же значение также отличается:
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
Вы не написали в чём же главное преимущество Loader'ов: их жизненный цикл отвязан от конкретной активности и управляется LoaderManager'ом. Это решает очень распространённую в 2.х проблему: вы начали загрузку чего-то тяжёлого в отдельном потоке (в асинктаске или руками созданном потоке, не суть), а активность пересоздалась (перевернули девайс). Асинтаска в панике — возвращать результат некуда, а вам нужно либо начинать загрузку заново либо придумывать велосипед по сохранению результатов загрузки. Loader'ы полностью решают эту проблему: вы просите у менеджера экземпляр лоадера по идентификатору. Если лоадер не был создан — менеджер его создаст, иначе — отдаст существующий экземпляр. То есть инициировать создание лоадера может одна активность, а получить результат уже совсем другая.

А на счёт Thread и AsyncTask я слышал мнение, что всегда предпочтительно использовать асинктаски (даже если операция никак не влияет на интерфейс), поскольку асинктаски используют общий пул потоков, что сводит к минимуму риск создания нового тяжеловесного потока.
UFO just landed and posted this here
Ох, зачем такие велосипеды городить для запуска повторяющихся задач. Есть же замечательные методы schedule и scheduleAtFixedRate что у Timer, что у (если хочется погибче управлять потоками) ScheduledExecutorService. По крайней мере, там не надо после каждого выполнения явно заказывать выполниться ещё раз.
Ну и небольшой оффтопик, в ListActivity не надо управлять видимостью ListView вручную, там автоматически оно скрывается и показывается вьюха с android:id="android:id/empty", для того такая Activity и есть не в последнюю очередь.
До недавнего времени хорошей практикой работы с БД было использование уже рассмотренных Thread и AsyncTask, но в Android 3.0 были добавлены такие классы как Loader и LoaderManager


Thread? AsyncTask? Правда? Ну если уж говорить о хороших практиках до Honeycomb, я бы упомянул в первую очередь как способ работы с БД, класс AsyncQueryHandler
К сказанному выше я бы хотел добавить, что, работая напрямую с Thread, следует иметь ввиду, что по-умолчанию новый поток создается с таким же приоритетом, что и UI-поток. И, если вы наплодите их штук 10, делающих более-менее серьёзную работу, об «отзывчивости» можете забыть. Я обычно в таких случаях руками понижаю приоритет до Process.THREAD_PRIORITY_BACKGROUND.
Sign up to leave a comment.