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

Интерфейс, диалоги, темы, стили, меню
Ответить
Dangreon
Сообщения: 41
Зарегистрирован: 01 янв 2013, 15:52

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

Сообщение Dangreon » 23 апр 2013, 14:43

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

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

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

Сообщение KamiSempai » 23 апр 2013, 17:05

Не вижу в этом проблемы. Один AsyncTask изменяет первый ProgressBar, другой изменяет второй ProgressBar.
Вот урок с получением промежуточных результатов: http://startandroid.ru/ru/uroki/vse-uro ... ltaty.html
В onProgressUpdate изменяйте нужный Вам ProgressBar.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Dangreon
Сообщения: 41
Зарегистрирован: 01 янв 2013, 15:52

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

Сообщение Dangreon » 26 апр 2013, 15:06

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

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

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

Сообщение KamiSempai » 26 апр 2013, 16:10

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
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Dangreon
Сообщения: 41
Зарегистрирован: 01 янв 2013, 15:52

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

Сообщение Dangreon » 26 апр 2013, 20:58

Ок! а при обращении к потоку UI не возникнет проблем? или надо как то особым образом это делать?

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

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

Сообщение KamiSempai » 26 апр 2013, 21:40

Dangreon писал(а):Ок! а при обращении к потоку UI не возникнет проблем? или надо как то особым образом это делать?
Если будете обращаться в onProgressUpdate проблем быть не должно, так как у AsyncTask для этого есть специальный Handler и все вызовы onProgressUpdate, а так-же onPostExecute, происходят только через него.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

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

Сообщение rezak90 » 27 апр 2013, 01:30

учти что на 3 > версий одновременно может быть запущенно не более пяти потоков, если запустить больше то система поставит их в очередь
R.id.team
Политика на форуме запрещена

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

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

Сообщение neoksi » 27 апр 2013, 06:44

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

spheros
Сообщения: 11
Зарегистрирован: 29 мар 2013, 18:36

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

Сообщение spheros » 03 май 2013, 16:24

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

spheros
Сообщения: 11
Зарегистрирован: 29 мар 2013, 18:36

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

Сообщение spheros » 04 май 2013, 16:53

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

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

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

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

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

Сообщение KamiSempai » 04 май 2013, 22:48

spheros писал(а):можно и не ограничиваться:

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

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

spheros
Сообщения: 11
Зарегистрирован: 29 мар 2013, 18:36

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

Сообщение spheros » 08 май 2013, 01:14

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);
}

Ответить