Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
gigs
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 397
#1

Progress Bar и мультипоточность - Программирование Android

29.02.2016, 00:03. Просмотров 423. Ответов 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 ?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.02.2016, 00:03     Progress Bar и мультипоточность
Посмотрите здесь:

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

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

Как менять message AlertDialog в зависимости от progress SeekBar? - Программирование Android
Доброго времени суток) В моём приложении при нажатии на TextVeiw появляется AlertDialog, в который я всунул SeekBar. Нужно, чтобы message...

Action Bar - Программирование Android
Помогите, пожалуйста, решить одну проблему. В IDEA ActionBar отображается, а когда перекидываю приложение на эмулятор то ActionBar'а...

Rating Bar -3-2-1 0 1 2 3 - Программирование Android
Можно ли стандартными средствами реализовать RatingBar вида -3 -2 -1 0 1 2 3 так чтобы прирощение звезд начиналось с нуля в обе...

Убрать Action bar - Программирование Android
Подскажите пожалуйста как убрать Action bar . Никак не получается все перепробовал вот мой манифест &lt;?xml version=&quot;1.0&quot;...

Изменение Title Bar - Программирование Android
Не нашел в интернете хорошего мануала, как можно изменить внешний вид стандартного title bar в приложении. Например сделать его другого...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DemD10
58 / 47 / 12
Регистрация: 03.09.2013
Сообщений: 434
29.02.2016, 00:10     Progress Bar и мультипоточность #2
Для чего setContentView(new TableMainLayout(context))?
gigs
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 397
29.02.2016, 00:13  [ТС]     Progress Bar и мультипоточность #3
Цитата Сообщение от DemD10 Посмотреть сообщение
Для чего setContentView(new TableMainLayout(context))?
это класс который генерит таблицу и наследует RelativeLayout
JavaStarter
11 / 11 / 3
Регистрация: 14.05.2015
Сообщений: 52
29.02.2016, 04:17     Progress Bar и мультипоточность #4
Я так понимаю, нужен 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();
                //что-то делаем с результатами
            }
        }
gigs
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 397
29.02.2016, 22:48  [ТС]     Progress Bar и мультипоточность #5
Воспользовался советом JavaStarter, но ProgressDialog так и не появляется. Я так понял что это из за того, что я в doInBackground использую runOnUiThread и получается что у меня два процесса исполняются в главном потоке, но так как в главном потоке не может исполнятся два процесса, оно тот процесс который начинается в onPreExecute перекрывает тем что исполняется в doInBackground.

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

Но в таком случае у меня возникает вопрос, как мне данные которые я буду доставать из базы в doInBackground, перенести потом в onPostExecute, если у меня в базе хранится больше 800 строк записей, я же не буду генерить 800 переменных и записывать в них данные с базы, как в таком случае поступить ?
CoolMind
418 / 401 / 65
Регистрация: 06.10.2012
Сообщений: 1,723
01.03.2016, 11:07     Progress Bar и мультипоточность #6
gigs, что-то ничего не понятно. Вы хоть поясните (без кода) последовательность шагов, чего вы хотите достичь. А то нарисовали всего один поток и запутались. Я бы ещё понял, если бы там было 2 потока (Thread).
AsyncTask вообще прост, если его изучить. Ну и ограничен очень. Попробуйте поизучать Thread или другие классы. Там даже проще будет в написании.
В onPostExecute никаких перерасчётов писать не надо, это накладно по времени, они все должны делаться в doInBackground.
Pablito
2419 / 1864 / 583
Регистрация: 12.05.2014
Сообщений: 6,604
Завершенные тесты: 1
01.03.2016, 11:41     Progress Bar и мультипоточность #7
setContentView не должен находиться в асинктаске
есть onCreate - там ему место
а уже из onCreate стартует асинктаск
gigs
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 397
02.03.2016, 02:01  [ТС]     Progress Bar и мультипоточность #8
CoolMind, хорошо, попробую объяснить понятнее. У меня есть класс TableMainLayout который с начало достает данные из базы (база состоит из 962 строк), потом создает Layout, в Layout создает таблицу и данные полученные из базы помещает в ячейки таблицы, в итоге создается таблица из 962 ячеек. Разумеется если этот класс запускать в основном потоке, то программа у меня виснет 5-6 сек. По этому я решил что AsyncTask поможет решить мне проблему с зависание, но оказалось что обработать такое количество данных с UI в doInBackground нельзя, а запускать класс в onPostExecute снова приводит к зависанию. Поэтому я пока не знаю как решить мне эту проблему.
CoolMind
418 / 401 / 65
Регистрация: 06.10.2012
Сообщений: 1,723
02.03.2016, 13:15     Progress Bar и мультипоточность #9
gigs, ага, теперь понятнее. Предполагаю, что вы уже знакомы с динамическим созданием таблицы.
Я сам делал таблицы через TableLayout, но предполагаю, что для ваших целей могут подойти ListView или GridView. Подскажите, вам нужно сколько столбцов вывести? Достаточно ли просто вывода данных и прокрутки? Или будете в таблице данные менять?
gigs
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 397
02.03.2016, 17:25  [ТС]     Progress Bar и мультипоточность #10
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 потом вмешивается мой класс. Какие могут быть решения этой проблемы ?
CoolMind
418 / 401 / 65
Регистрация: 06.10.2012
Сообщений: 1,723
02.03.2016, 18:11     Progress Bar и мультипоточность #11
gigs, в общем, насколько я понял, вам не требуется компонент TableLayout. Возьмите RecyclerView или ListView и настройте его. Любой из этих двух компонентов очень быстро отобразит вам несколько записей на экране, а остальные создавать не будет, пока вы не начнёте прокручивать. Уроков по этим компонентам на любом Android-ресурсе полно. Собственно, это основная задача после получения данных из БД в Android. Учтите, что надо работать через ViewHolder, другие уроки не читайте.
gigs
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 397
02.03.2016, 22:16  [ТС]     Progress Bar и мультипоточность #12
CoolMind, да нет, мне как раз и надо TableLayout, мне нужна таблица из 44 столбцов и 21 строки. Что посоветуете в таком случае ?
CoolMind
418 / 401 / 65
Регистрация: 06.10.2012
Сообщений: 1,723
02.03.2016, 23:38     Progress Bar и мультипоточность #13
gigs, насколько я понял, TableLayout у вас будет вложен внутрь ScrollView и HorizontalScrollView. Это годное решение, я тоже так делал. Не знаю, в этом случае вам надо правильно обработать ситуацию создания компонентов. Насколько я понял, у вас в этом случае колёсико прокрутки подвисало. Можно, в принципе, всё делать через addView в цикле.
gigs
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 397
03.03.2016, 15:35  [ТС]     Progress Bar и мультипоточность #14
CoolMind, в принципе знаешь что я придумал. Можно вместо бара, просто выводить сообщение типа "Подождите идет загрузка" и не заморачиваться с этими барами. Тут уже как бы дело эстетики, пользователю по большой мере все равно, что там будет, бар или сообщение, главное чтоб был результат.
CoolMind
418 / 401 / 65
Регистрация: 06.10.2012
Сообщений: 1,723
03.03.2016, 15:54     Progress Bar и мультипоточность #15
gigs, это хороший подход. Можно также объединить в одном выводе и прогрессбар, и сообщение. Тем более, что сообщение можно по ходу дела менять.
gigs
8 / 9 / 1
Регистрация: 21.12.2011
Сообщений: 397
03.03.2016, 17:32  [ТС]     Progress Bar и мультипоточность #16
CoolMind, спасибо за советы. Тему можно закрывать.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.03.2016, 18:36     Progress Bar и мультипоточность
Еще ссылки по теме:

.APK to .BAR With OpenGL - Программирование Android
Добрый день. Если кто в курсе, подскажите пожалуйста существуют ли ограничения или какие либо проблемы при портировании приложения...

Убpать веpхний Action Bar - Программирование Android
Как убpать веpхний баp?!

Полностью прозрачный status bar - Программирование Android
Как сделать прозрачный статус бар как на картинке: и чтобы изображение было под статус баром.

Приложение без Title bar - Программирование Android
Делаю так (як нагуглил): super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); ...

Split Action Bar не работает - Программирование Android
Здравствуйте, я создал иконку в actionbar, файл res/menu/menu_main.xml и хочу чтобы она находилась на нижней части экрана. &lt;item...


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

Или воспользуйтесь поиском по форуму:
CoolMind
418 / 401 / 65
Регистрация: 06.10.2012
Сообщений: 1,723
03.03.2016, 18:36     Progress Bar и мультипоточность #17
gigs, не за что!
Если понадобится сделать с таблицей фокус как в Excel'е, обращайтесь. Имею в виду прокрутку таблицы в любом направлении, но чтобы заголовки столбцов и строк оставались на экране и прокручивались одновременно с данными.
Yandex
Объявления
03.03.2016, 18:36     Progress Bar и мультипоточность
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru