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

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

Восстановить пароль Регистрация
 
Paket236
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 48
07.11.2016, 17:00     Обновление ProgressBar из основного потока #1
Здравствуйте!
Итак, имеется долго выполняющийся код [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].
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.11.2016, 17:00     Обновление ProgressBar из основного потока
Посмотрите здесь:

progressbar Android
Android Обновление ProgressBar во время длительной операции
Android ProgressBar
При сдвиге основного экрана Activity карта становится черного цвета Android
Android Браузер в маленьком окошке основного окна
Как можно в progressBar вернуть прогресс нужного потока? Android
Android Почему падает программа до исполнения основного кода
Android Рисование на фоне основного Layout-а, возможно ли?

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kondusov
2 / 2 / 0
Регистрация: 01.06.2013
Сообщений: 152
07.11.2016, 17:31     Обновление ProgressBar из основного потока #2
Paket236, можно воспользоваться способом со вторым потоком, а чтобы код 2 не выполнился раньше кода 1, сделать флаг, который выставлялся бы в true только после выполнения большого цикла, и в коде 2 соответственно делать проверку if (flag){.....}
Paket236
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 48
07.11.2016, 17:47  [ТС]     Обновление ProgressBar из основного потока #3
kondusov, не совсем Вас понял. В каком потоке должен находиться код [2] ? Если в неосновном (оба кода), то такая проверка (if) не нужна (но такой вариант, как я уже упомянул, когда оба кода в неосновном потоке, меня пугает... хотя, возможно, лучше не придумать). Если в основном, то код [2] просто пропустится (можно сделать не if(), а while{}, чтобы подождать, но тогда UI подвиснет и не будет обновляться ProgressBar). Можете пример привести для ясности?
kondusov
2 / 2 / 0
Регистрация: 01.06.2013
Сообщений: 152
07.11.2016, 18:07     Обновление ProgressBar из основного потока #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();
        //---------------------------------------------
        
    }
}

Писал с телефона, но вроде должно работать
ExFau$t
55 / 55 / 4
Регистрация: 08.05.2012
Сообщений: 448
07.11.2016, 21:34     Обновление ProgressBar из основного потока #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();
                                                    }
                                                });
Paket236
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 48
08.11.2016, 12:53  [ТС]     Обновление ProgressBar из основного потока #6
kondusov, спасибо! Не то, что я хотел, но лучше вроде и не сделать. Воспользуюсь именно Вашим вариантом.
Yandex
Объявления
08.11.2016, 12:53     Обновление ProgressBar из основного потока
Ответ Создать тему
Опции темы

Текущее время: 09:21. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru