Страница 1 из 1

AsyncTask и ProgressBar, асинхронно.

Добавлено: 23 апр 2013, 14:43
Dangreon
Мне необходимо уметь одновременно отображать больше одного работающего прогрессбара, который получает информацию о прогрессе с помощью отдельного asynctask. Т.е. когда запускается одна задача, под нее есть свой прогрессбар и создается свой асинктаск, и мы одновременно видим эти прогрессы. Как это можно реализовать? Пока никак не могу придумать..

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 23 апр 2013, 17:05
KamiSempai
Не вижу в этом проблемы. Один AsyncTask изменяет первый ProgressBar, другой изменяет второй ProgressBar.
Вот урок с получением промежуточных результатов: http://startandroid.ru/ru/uroki/vse-uro ... ltaty.html
В onProgressUpdate изменяйте нужный Вам ProgressBar.

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 26 апр 2013, 15:06
Dangreon
Ок, а если реализовать через holder ? Далее, когда версия андроида <1.5 и >4, AsyncTask'и выполняются последовательно... У асинтаска все же
есть метод, чтобы запустить параллельно, это метод связан с executor. не пойму, как его согласовать с doInBackground ?

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 26 апр 2013, 16:10
KamiSempai
Dangreon писал(а):Ок, а если реализовать через holder ? Далее, когда версия андроида <1.5 и >4, AsyncTask'и выполняются последовательно... У асинтаска все же
есть метод, чтобы запустить параллельно, это метод связан с executor. не пойму, как его согласовать с doInBackground ?
Так вон оно что! Оказывается начиная с версии API 11 AsyncTask'и выполняются не с помощью внутреннего статичного ThreadPoolExecutor, а с помощью внутреннего класса SerialExecutor реализующего интерфейс Executor. А этот SerialExecutor выполняет задачи не параллельно, а последовательно.
Единственное решение использовать метод executeOnExecutor и передавать в него свой Executor, например, ThreadPoolExecutor.
Может быть даже подойдет ThreadPoolExecutor из более поздних версий андроида. Вот часть кода нагло скопированная из Андроида 2.2 :[syntax=java]private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 10;

private static final BlockingQueue<Runnable> sWorkQueue = new LinkedBlockingQueue<Runnable>(
10);

private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);

public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};

private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);[/syntax]Только стоит учесть еще одну мелочь, executeOnExecutor появился только в API 11

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 26 апр 2013, 20:58
Dangreon
Ок! а при обращении к потоку UI не возникнет проблем? или надо как то особым образом это делать?

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 26 апр 2013, 21:40
KamiSempai
Dangreon писал(а):Ок! а при обращении к потоку UI не возникнет проблем? или надо как то особым образом это делать?
Если будете обращаться в onProgressUpdate проблем быть не должно, так как у AsyncTask для этого есть специальный Handler и все вызовы onProgressUpdate, а так-же onPostExecute, происходят только через него.

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 27 апр 2013, 01:30
rezak90
учти что на 3 > версий одновременно может быть запущенно не более пяти потоков, если запустить больше то система поставит их в очередь

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 27 апр 2013, 06:44
neoksi
rezak90 писал(а):учти что на 3 > версий одновременно может быть запущенно не более пяти потоков, если запустить больше то система поставит их в очередь
Эх, во всем нас ограничивают :D.

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 03 май 2013, 16:24
spheros
rezak90 писал(а):учти что на 3 > версий одновременно может быть запущенно не более пяти потоков, если запустить больше то система поставит их в очередь
Похоже, при этом система засовывает потоки в группы по 5 штук в каждую. Потоки внутри группы выполняются параллельно. Группы же потоков выполняются последовательно. По крайней мере она ведет себя так в версии 15 при запуске задач с помощью executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 04 май 2013, 16:53
spheros
neoksi писал(а):
rezak90 писал(а):учти что на 3 > версий одновременно может быть запущенно не более пяти потоков, если запустить больше то система поставит их в очередь
Эх, во всем нас ограничивают :D.
можно и не ограничиваться:

Код: Выделить всё

ExecutorService executor = Executors.newFixedThreadPool(PoolSize);
someAsyncTask.executeOnExecutor(executor);

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 04 май 2013, 22:48
KamiSempai
spheros писал(а):можно и не ограничиваться:

Код: Выделить всё

ExecutorService executor = Executors.newFixedThreadPool(PoolSize);
someAsyncTask.executeOnExecutor(executor);
А это точно будет работать? На сколько я понял, ограничение идет на процесс. Иначе какой в нем смысл?

Re: AsyncTask и ProgressBar, асинхронно.

Добавлено: 08 май 2013, 01:14
spheros
KamiSempai писал(а):
spheros писал(а):можно и не ограничиваться:

Код: Выделить всё

ExecutorService executor = Executors.newFixedThreadPool(PoolSize);
someAsyncTask.executeOnExecutor(executor);
А это точно будет работать? На сколько я понял, ограничение идет на процесс. Иначе какой в нем смысл?
пардон. я имел в виду примерно следующее:

Код: Выделить всё

ExecutorService executor = Executors.newFixedThreadPool(PoolSize);
for(int i = 1; i <= TasksNumber; i++) {
	new SomeAsyncTask().executeOnExecutor(executor);
}
Хотя, пожалуй было бы "правильнее" в качестве своего executor-а использовать THREAD_POOL_EXECUTOR из AsyncTask-а с модифицированным параметром CORE_POOL_SIZE:

Код: Выделить всё

//private static final int CORE_POOL_SIZE = 5;
private static final int CORE_POOL_SIZE = YourPoolSize;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;

private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);
        public Thread newThread(Runnable r) {
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
};

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

private static final Executor executor = 
            new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);


for(int i = 1; i <= TasksNumber; i++) {
	new SomeAsyncTask().executeOnExecutor(executor);
}