Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 401

Progress Bar и мультипоточность

29.02.2016, 00:03. Показов 1991. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, имеется клас который достает данные с базы данных и генерит на их основе таблицу TableLayout, когда я его вызываю в onCreate() мое приложение висит 5 секунд и потом на экране появляется сгенерированная таблица. Вопрос в том как сделать так чтоб эти 5 секунд приложение не висло, а отображало на экране крутящийся бар.

Я делал так с помощью AsyncTask:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class DoWork extends AsyncTask<Void, Void, Void>{
    Context context;
 
    public DoWork(Context con){
        this.context = con;
    }
 
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        setContentView(R.layout.content_progress);
        pb = (ProgressBar) findViewById(R.id.progressBar);
        pb.setVisibility(View.VISIBLE);
    }
 
    @Override
    protected Void doInBackground(Void... params) {
        runOnUiThread(new Runnable() {
            public void run() {
                setContentView(new TableMainLayout(context));
            }
        });
 
        return null;
    }
 
    @Override
    protected void onPostExecute(Void result) {
 
        pb.setVisibility(View.INVISIBLE);
        super.onPostExecute(result);
    }
}
Код content_progress.xml
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.standart.trainschedule.ProgressActivity"
    tools:showIn="@layout/activity_progress">
 
    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>
new TableMainLayout(context) - это клас который генерит таблицу

Проблема в том что прогресс бар который я сделал в xml не отображается, я думаю что это из за того что в doInBackground() я снова вызываю setContentView(new TableMainLayout(context)); и оно заменяет setContentView из onPreExecute().

Как можно сделать так чтоб не использовать два раза setContentView ?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.02.2016, 00:03
Ответы с готовыми решениями:

Progress Bar
Здравствуйте, хочу сделать Progress Bar круглым внутри, данный код меняет только края заднего фона, стартовую и конечную точку прогресса, а...

Сменить цвет progress bar программно
Привет. Собственно сабж. Что я понял, фон прогресс бара хранится в drawable в 3-х слоях, это бэкгроунд, вторичный прогресс и прогресс...

Progress Button, как вызвать метод, а после закончить Progress?
Есть кнопка с прогрессом, по ее клику вызывается это: private void sendProgress (final LinearProgressButton button){ ...

16
59 / 48 / 13
Регистрация: 03.09.2013
Сообщений: 474
29.02.2016, 00:10
Для чего setContentView(new TableMainLayout(context))?
0
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 401
29.02.2016, 00:13  [ТС]
Цитата Сообщение от DemD10 Посмотреть сообщение
Для чего setContentView(new TableMainLayout(context))?
это класс который генерит таблицу и наследует RelativeLayout
0
11 / 11 / 4
Регистрация: 14.05.2015
Сообщений: 52
29.02.2016, 04:17
Я так понимаю, нужен ProgressDialog, а не ProgressBar. Я делал так:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Override
        protected void onPreExecute() {
            dialog = new ProgressDialog(MainActivity.this);
            dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            dialog.setMessage("Loading…");
            dialog.setCancelable(false);
            dialog.show();
        }
 
 
@Override
        protected Void doInBackground(Void... params) {
            try {
 
                //делаем что нам нужно, во время операции крутится progressdialog
 
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return list;
 
        }
 
@Override
        protected void onPostExecute() {
            if (dialog.isShowing()) {
                //отключаем progressdialog
                dialog.dismiss();
                //что-то делаем с результатами
            }
        }
0
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 401
29.02.2016, 22:48  [ТС]
Воспользовался советом JavaStarter, но ProgressDialog так и не появляется. Я так понял что это из за того, что я в doInBackground использую runOnUiThread и получается что у меня два процесса исполняются в главном потоке, но так как в главном потоке не может исполнятся два процесса, оно тот процесс который начинается в onPreExecute перекрывает тем что исполняется в doInBackground.

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

Но в таком случае у меня возникает вопрос, как мне данные которые я буду доставать из базы в doInBackground, перенести потом в onPostExecute, если у меня в базе хранится больше 800 строк записей, я же не буду генерить 800 переменных и записывать в них данные с базы, как в таком случае поступить ?
0
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
01.03.2016, 11:07
gigs, что-то ничего не понятно. Вы хоть поясните (без кода) последовательность шагов, чего вы хотите достичь. А то нарисовали всего один поток и запутались. Я бы ещё понял, если бы там было 2 потока (Thread).
AsyncTask вообще прост, если его изучить. Ну и ограничен очень. Попробуйте поизучать Thread или другие классы. Там даже проще будет в написании.
В onPostExecute никаких перерасчётов писать не надо, это накладно по времени, они все должны делаться в doInBackground.
0
2884 / 2296 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
01.03.2016, 11:41
setContentView не должен находиться в асинктаске
есть onCreate - там ему место
а уже из onCreate стартует асинктаск
0
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 401
02.03.2016, 02:01  [ТС]
CoolMind, хорошо, попробую объяснить понятнее. У меня есть класс TableMainLayout который с начало достает данные из базы (база состоит из 962 строк), потом создает Layout, в Layout создает таблицу и данные полученные из базы помещает в ячейки таблицы, в итоге создается таблица из 962 ячеек. Разумеется если этот класс запускать в основном потоке, то программа у меня виснет 5-6 сек. По этому я решил что AsyncTask поможет решить мне проблему с зависание, но оказалось что обработать такое количество данных с UI в doInBackground нельзя, а запускать класс в onPostExecute снова приводит к зависанию. Поэтому я пока не знаю как решить мне эту проблему.
0
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
02.03.2016, 13:15
gigs, ага, теперь понятнее. Предполагаю, что вы уже знакомы с динамическим созданием таблицы.
Я сам делал таблицы через TableLayout, но предполагаю, что для ваших целей могут подойти ListView или GridView. Подскажите, вам нужно сколько столбцов вывести? Достаточно ли просто вывода данных и прокрутки? Или будете в таблице данные менять?
0
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 401
02.03.2016, 17:25  [ТС]
CoolMind, как создавать динамические таблицы я знаю. На данный момент мне достаточно только прокрутки, но в будущем я хочу добавить еще фильтр на подобии того, что используется в Excel, но это все будет потом. Сейчас мне надо сделать так, чтоб вся генерация таблицы происходила в отдельном потоке, а на экране в это время отображался только крутящийся бар. Но проблема в том, насколько я понимаю, что в андроид нельзя производить манипуляции с UI элементами, не в UI потоке(главном потоке).

В интернете есть много уроков о том как работает AsyncTask, но все они объясняют только как что то скачать с интернета и чтоб во время скачивания экран не вис, а крутился какой то бар. Здесь как бы понятно, мы качаем данные с интернета и UI элементы не трогаем, бар себе крутится и все нормально. У меня же другая ситуация, я ничего не скачиваю, но у меня нужно сгенерировать очень много UI элемент, где то приблизительно 900 штук, но как это сделать чтоб не задевать главный поток ?

Я уже даже немного переписал код, теперь у меня в doInBackground идет выборка данных из базы в ArrayList, а в onPostExecute я передаю данные из ArrayList в конструктор класса new TableMainLayout(context, product, shop, price) который потом с этими данными генерит таблицу:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class DoWork extends AsyncTask<Void, Void, Void>{
 
    Context context;
 
    private ArrayList<String> product = new ArrayList<>();
    private ArrayList<String> shop = new ArrayList<>();
    private ArrayList<String> price = new ArrayList<>();
 
    public DoWork(Context con){
        this.context = con;
    }
 
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
            dialog = new ProgressDialog(ScheduleActivity2.this);
            dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            dialog.setMessage("Loading…");
            dialog.setIndeterminate(true);
            dialog.setCancelable(false);
            dialog.show();
    }
 
    @Override
    protected Void doInBackground(Void... params) {
       
            for(int i = 1; i <= 23; i++){
                product.add(dataBase.getData(i, "product_table", "product_name"));
            }
            for(int i = 1; i <= 35; i++){
                shop.add(dataBase.getData(i, "shop_table", "shop_name"));
            }
            for(int i = 1; i <= 805; i++){
                price.add(dataBase.getData(i, "price_table", "price"));
            }
 
        return null;
    }
 
    @Override
    protected void onPostExecute(Void result) {
 
        setContentView(new TableMainLayout(context, product, shop, price));
 
        dialog.dismiss();
        super.onPostExecute(result);
    }
}
теперь когда программа начинает запускать doInBackground, бар на экране крутится, но когда программа переходит в onPostExecute там где я вызываю класс new TableMainLayout, бар виснет и не крутится секунд 4 и потом на экране появляется уже сгенерированая таблица. Опять же, бар виснет из за того, что в главный UI потом вмешивается мой класс. Какие могут быть решения этой проблемы ?
0
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
02.03.2016, 18:11
gigs, в общем, насколько я понял, вам не требуется компонент TableLayout. Возьмите RecyclerView или ListView и настройте его. Любой из этих двух компонентов очень быстро отобразит вам несколько записей на экране, а остальные создавать не будет, пока вы не начнёте прокручивать. Уроков по этим компонентам на любом Android-ресурсе полно. Собственно, это основная задача после получения данных из БД в Android. Учтите, что надо работать через ViewHolder, другие уроки не читайте.
0
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 401
02.03.2016, 22:16  [ТС]
CoolMind, да нет, мне как раз и надо TableLayout, мне нужна таблица из 44 столбцов и 21 строки. Что посоветуете в таком случае ?
0
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
02.03.2016, 23:38
gigs, насколько я понял, TableLayout у вас будет вложен внутрь ScrollView и HorizontalScrollView. Это годное решение, я тоже так делал. Не знаю, в этом случае вам надо правильно обработать ситуацию создания компонентов. Насколько я понял, у вас в этом случае колёсико прокрутки подвисало. Можно, в принципе, всё делать через addView в цикле.
1
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 401
03.03.2016, 15:35  [ТС]
CoolMind, в принципе знаешь что я придумал. Можно вместо бара, просто выводить сообщение типа "Подождите идет загрузка" и не заморачиваться с этими барами. Тут уже как бы дело эстетики, пользователю по большой мере все равно, что там будет, бар или сообщение, главное чтоб был результат.
0
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
03.03.2016, 15:54
gigs, это хороший подход. Можно также объединить в одном выводе и прогрессбар, и сообщение. Тем более, что сообщение можно по ходу дела менять.
1
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 401
03.03.2016, 17:32  [ТС]
CoolMind, спасибо за советы. Тему можно закрывать.
0
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
03.03.2016, 18:36
gigs, не за что!
Если понадобится сделать с таблицей фокус как в Excel'е, обращайтесь. Имею в виду прокрутку таблицы в любом направлении, но чтобы заголовки столбцов и строк оставались на экране и прокручивались одновременно с данными.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.03.2016, 18:36
Помогаю со студенческими работами здесь

Можно ли переделать Progress bar в Track bar?
Можно ли переделать Progress bar в Track bar? От прогресбара нужно всего лишь, что бы можно было перемещать внутри его (заливку) ползунок.

progress bar
Написала код для простенького web браузера вот код brouser.h #ifndef BROWSER_H #define BROWSER_H #include...

Progress bar
Как сделать Progress bar? Контроллер обрабатывает большое количество данных, отсылаю их по апи в 1с, хочу чтобы на странице отображался...

Progress bar
Я собственно совсем новичок в программировании, так что не ругайтесь строго. Вопрос вот в чем, у меня есть одна форма, с определенными...

progress bar
Вообщем суть в этом у меня есть 3 формы в первой форме заполняются эдит1 потом открывается идет отправка этого сообщения на мэйл и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru