Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 86
1

Обновление ProgressBar из основного потока

07.11.2016, 17:00. Показов 2034. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!
Итак, имеется долго выполняющийся код [1], внутри которого время от времени должно обновляться значение ProgressBar. Следом идёт другой код [2], который должен выполняться только после выполнения кода [1].
Java:
Кликните здесь для просмотра всего текста
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
public class MainActivity extends Activity {
 
    ProgressBar progressBar1;
 
    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
    }
 
    public void onClickButton(View v) {
        Toast.makeText(this, "Кнопка нажата!", Toast.LENGTH_LONG).show();
 
        // [1]
        //---------------------------------------------
        // Симуляция долгих вычислений
        int i=0;
        for(i=0; i<=15; i++) {
            Log.e("Main", "i: " + i);
            
            progressBar1.setProgress(i);
            
            StringBuilder sb = new StringBuilder();
            sb.append(true);
            sb.append(10);
            for(int j=0; j<=20000; j++) {
                sb.append(10);
                sb.delete(0, 1);
            }
        }
        //---------------------------------------------
        
        // [2]
        if(i==15) {
            // выполняется после окончания кода выше
        }
    }
}

xml:
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 
    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClickButton"
        android:text="Пуск" />
    
    <ProgressBar
        android:id="@+id/progressBar1"
        android:layout_below="@id/btn1"
        android:background="#0faa"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:max="15"
        android:progress="0" />
 
</RelativeLayout>

Проблема в том, что значение ProgressBar обновится только 1 раз и только в конце выполнения основного потока (что вроде логично, но мне не подходит). Можно было бы долго выполняющийся участок кода [1] занести в отдельный поток, а внутри в runOnUiThread(...) обновлять ProgressBar, но тогда код [2] выполнится раньше кода [1], что тоже не подходит. Можно было бы и код [1], и код [2] занести в отдельный поток (чтобы сохранить последовательность выполнения), но такой вариант меня немного пугает, т.к. код [2] довольно большой, в примере он для наглядности упрощён.

Какие могут быть решения?
Т.е., другими словами, сначала должен выполниться код [1], в нём должен обновляться ProgressBar, затем после кода [1] должен выполниться код [2].
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.11.2016, 17:00
Ответы с готовыми решениями:

Обновление формы происходит из побочного потока вместо основного
задача: сделать так, что бы при запуске программы запускалось окно, потом оно блокировалось, внизу...

Выполнение слота основного потока через сигнал второстепенного потока
Доброго времени суток! Вопрос следующий. В основном потоке создается кнопка и Qlabel class...

Вызов метода основного потока из второстепенного потока
Здравствуйте! Столкнулся с проблемой: есть два потока (основной и не основной), мне нужно вызвать...

Вызов SaveFileDialog не из основного потока
Есть форма в которой расположен richtextBox для вывода содержимого файла истории сообщений. Хочу...

5
4 / 4 / 0
Регистрация: 01.06.2013
Сообщений: 153
07.11.2016, 17:31 2
Paket236, можно воспользоваться способом со вторым потоком, а чтобы код 2 не выполнился раньше кода 1, сделать флаг, который выставлялся бы в true только после выполнения большого цикла, и в коде 2 соответственно делать проверку if (flag){.....}
0
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 86
07.11.2016, 17:47  [ТС] 3
kondusov, не совсем Вас понял. В каком потоке должен находиться код [2] ? Если в неосновном (оба кода), то такая проверка (if) не нужна (но такой вариант, как я уже упомянул, когда оба кода в неосновном потоке, меня пугает... хотя, возможно, лучше не придумать). Если в основном, то код [2] просто пропустится (можно сделать не if(), а while{}, чтобы подождать, но тогда UI подвиснет и не будет обновляться ProgressBar). Можете пример привести для ясности?
0
4 / 4 / 0
Регистрация: 01.06.2013
Сообщений: 153
07.11.2016, 18:07 4
Paket236,
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
49
50
51
52
public class MainActivity extends Activity {
 
    ProgressBar progressBar1;
    Handler h;
 
    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
 
       h = new Handler() {
           public void handleMessage(android.os.Message msg) {
             // обновляем прогрессбар
             progressBar1.setProgress(Integer.valueOf(msg.what)); // не знаю что просит на вход метод setProgress, вроде прокатит
             if (Integer.valueOf(msg.what) == 15)
                //здесь Ваш код при i == 15
           };
       };
 
        
    }
 
    public void onClickButton(View v) {
        Toast.makeText(this, "Кнопка нажата!", Toast.LENGTH_LONG).show();
 
        // [1]
        //---------------------------------------------
        // Симуляция долгих вычислений 
       Thread t = new Thread(new Runnable() {
      public void run() {
        int i=0;
        for(i=0; i<=15; i++) {
            Log.e("Main", "i: " + i);
            
             h.sendEmptyMessage(i);
            
            StringBuilder sb = new StringBuilder();
            sb.append(true);
            sb.append(10);
            for(int j=0; j<=20000; j++) {
                sb.append(10);
                sb.delete(0, 1);
            }
        }
        }
      }
    });
    t.start();
        //---------------------------------------------
        
    }
}

Писал с телефона, но вроде должно работать
1
1570 / 1168 / 426
Регистрация: 08.05.2012
Сообщений: 5,219
07.11.2016, 21:34 5
Большой код в Thread или AcyncTask, туда mDialog.mDialog2.setProgress(progress); . Прогрессбар:
Java
1
2
3
4
5
6
7
8
9
10
11
12
 myHandler.post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        ProgressDialog mDialog = new ProgressDialog(act);
                                                        mDialog.setMessage("Message");
                                                        mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                                                        mDialog.setProgress(0);
                                                        mDialog.setTitle("Title");
                                                        mDialog.setMax(MAX);
                                                        mDialog.show();
                                                    }
                                                });
0
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 86
08.11.2016, 12:53  [ТС] 6
kondusov, спасибо! Не то, что я хотел, но лучше вроде и не сделать. Воспользуюсь именно Вашим вариантом.
0
08.11.2016, 12:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.11.2016, 12:53
Помогаю со студенческими работами здесь

Выпадение из основного потока - пересечение
Здравствуйте! Сразу прилагаю код, а то уже 3 дня по вечерам бюсь об монитор головой и ничего...

Вызов основного потока из фонового
Добрый день! Нужно выполнить некий код в отдельном потоке. По завершению выполнения, необходимо...

Запись в Textbox не из основного потока
Доброе утро. Прошу помочь. Столкнулась со следующей проблемой. Есть элемент формы Textbox в него...

Доступ к элементу управления не из основного потока
Подскажите как решить такую проблему: в моей программе есть ListBox, который, естественно, создан в...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru