Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Отрисовка данных в отдельном потоке

Уважаемые гуру и простые хорошие ребята, подскажите как правильно реализовать отрисовку графики в отдельном потоке?
С потоками только начинаю знакомство, почитал документацию, теоритически я теперь подкован, но на практике не знаю как лучше всё это дело реализовать.

Моя программа получает данные с акселерометра и выводит данные в график(подключена библиотека AndroidPlot).
Из-за этого интерфейс программы начинает тормозить, скролл работает с рывками и т.д.

Сейчас отрисовка графики у меня происходит в методе onSensorChanged(). Т.е. каждый раз при изменении показаний датчика запускается код рисования. Как запустить onSensorChanger() в отдельном потоке?
Ответ: Паблито, может я не правельно выразился, понятно что отрисовка в юай треде, а все остальное в тредпул
Вопрос: Вынести загрузку и парсинг в отдельный поток

Ребята,привет.
Есть приложение,калькулятор и есть активность валюта,где конвертация валюты происходит,так вот оно берет с сайта yahooapis.com котировки валют.
Писал я это приложение по статье одной известной и в качестве примера там показывалось ,как будет происходить загрузка котировок валют ,а в это время время пользователю будет показана заставка.Все длится это около 10 сек,это очень долго сидеть ждать 10 сек уставившись на одну картинку.

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

Как реализовать,я не догоняю,получается у меня обращение к сайту с котировками идет через активность,следовательно нужно эту активность вынести в отдельный поток?Но активности разве разносятся по потокам?

Добавлено через 1 час 24 минуты
Сделал,ребята,кому интересно расскажу.
Ту активи, которая синхронизировалась с сайтом курс валют,я разобрал,и создал AsyncTask непостредственно в активности конвертация валюты...
Спасибо за ответы)))
Ответ: Не нагрузишь, не за что. Удачи.
Вопрос: Как вынести подключение к БД в отдельный поток?

Как вынести подключение бд в отдельный поток???Вот код программы:
Java(TM) 2 Platform Standard Edition 5.0
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
53
54
55
56
57
import android.os.Bundle;
import android.view.View;
import android.app.Activity;
import android.widget.Button;
import android.widget.TextView;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
public class MainActivity extends Activity {
 
    TextView textView;
    Button button;
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        textView = (TextView) findViewById(R.id.textView);
        button = (Button) findViewById(R.id.button);
 
        button.setOnClickListener(new View.OnClickListener() {
 
            @Override
            public void onClick(View v) {
 
                try {
                    Connection conn = null;
                    String url = "jdbc:jtds:sqlserver://localhost:.../databaseName=master";
                    String name = "...";
                    String password = "...";
 
                    try {
                        Class.forName("net.sourceforge.jtds.jdbc.Driver");
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
 
                    try {
                        conn = DriverManager.getConnection(url, name, password);
                        textView.setText("я подключился");
                    } catch (SQLException e) {
                        e.printStackTrace();
                        textView.setText("какой-то косяк");
                    }
 
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
 
        });
    }
}
Добавлено через 1 минуту
Вот что она выдает на выходе:
Кликните здесь для просмотра всего текста
03-04 08:59:28.556 28929-28929/com.example.ls.connection_ms_sql W/System.err: android.os.NetworkOnMainThreadException
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at java.net.InetAddress.getByName(InetAddress.java:305)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at java.net.InetSocketAddress.<init>(InetSocketAddress.java:105)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at java.net.InetSocketAddress.<init>(InetSocketAddress.java:90)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at net.sourceforge.jtds.jdbc.SharedSocket.createSocketForJDBC3(SharedSocket.java:279)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at net.sourceforge.jtds.jdbc.SharedSocket.<init>(SharedSocket.java:251)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at net.sourceforge.jtds.jdbc.JtdsConnection.<init>(JtdsConnection.java:331)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at java.sql.DriverManager.getConnection(DriverManager.java:179)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at java.sql.DriverManager.getConnection(DriverManager.java:213)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at com.example.ls.connection_ms_sql.MainActivity$1.onClick(MainActivity.java:43)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at android.view.View.performClick(View.java:4770)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at android.view.View$PerformClick.run(View.java:19801)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at android.os.Looper.loop(Looper.java:135)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5261)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at java.lang.reflect.Method.invoke(Native Method)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at java.lang.reflect.Method.invoke(Method.java:372)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:939)
03-04 08:59:28.568 28929-28929/com.example.ls.connection_ms_sql W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:734)
Ответ: Вася, я тебе отписал в соседней теме, ты хоть бы зашел туда, отписался о прогрессе
и код на форум помещай в теги, 21-й век на дворе
Вопрос: MediaPlayer и новый поток для воспроизведения

Собственно читаю сейчас документацию, хочу сделать аудиоплеер, только не знаю,нужно ли создавать отдельный поток для воспроизведения музыки? Ведь, как я понимаю с теории и практики, в потоке все действия обрабатываются поочередно,а я хочу,чтоб пользователь мог взаимодействовать с интерфейсом во время проигрывания.

Что я точно понял,что новый поток нужно создавать перед воспроизведением файла. И делает это метод prepareAsync() . Но, если я правильно понимаю, это поток только для подготовки(буферизация и т.д.). К тому же,если воспроизводить файлы в "правильном формате" папки raw проекта, подготовка не требуется. Немного сумбурно,но надеюсь суть вопроса ясна)
Ответ: okunetsky, поток не нужен если вы просто даёте плееру трек. Ваш код помог бы ответить точнее
Вопрос: Изменения массива не "замечает" поток

Здравствуйте! Пишу программу под андроид, и в коде наблюдалась странная проблема - при изменении значений переменной, отдельный поток просто не замечал этого. Переписал код на чистый java, та же проблема. Помогите пожалуйста, из-за чего данная проблема?
Например, если сначала ввести set test, а потом start - выведет а.

Буду очень благодарен за помощь!
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
import java.util.*;
 
public class TestBug
{
    String[] test = {"a"};
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (true) {
            String[] inData = sc.nextLine().split(" ");
 
            switch (inData[0]) {
                case "start":
                    new TestBug().run();
                    break;
                case "set":
                    new TestBug().setMsg(inData[1]);
                    break;
            }
        }
        
    }
    
    public void setMsg(String data) {
        test[0] = data;
        System.out.println("Succ");
        System.out.println(Arrays.deepToString(test));
    }
 
    public void run() {
        new Thread(new Runnable() {
                @Override
                public void run()
                {
                    while (true) {
                        try {
                            Thread.sleep(5000L);
                            System.out.println(Arrays.deepToString(test));
                        }
                        catch (InterruptedException e)
                        {}
                    }
                }
            }).start();
        }
}
Добавлено через 6 минут
Как выяснилось - поток вообще ни на что ни влияет. Оно в любом случае выдает не тот ответ
Ответ: Правильно - ни потоки, ни ОС здесь роли не играют... Обычное ООП... Класс TestBug, поле test не статическое... А, вы каждый раз создаете новый экземпляр, меняете поле в одном экземпляре, а, используете в другом, поэтому оно и теряется.

Сделайте так, и будет работать:

Java
1
2
3
TestBug testBug = new TestBug();
testBug.setMsg(inData[1]);
testBug.run();
Вопрос: Как заставить поток ждать

Есть программа, в которую пользователь может залогиниться, за залогинивание отвечает отдельный поток, который обращается к серверу и получает от него ответ. Мне необходимо, чтобы поток выполнял код внутри цикла лишь раз, после чего засыпал, пока его не разбудит пользователь повторным нажатием кнопки войти. К сожалению, приведенный ниже код выдает ошибку "java.lang.IllegalMonitorStateException: object not locked by thread before wait()".
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
53
54
55
56
57
58
59
60
61
62
63
package ru.utccom.utc;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
 
 
public class MainActvt extends AppCompatActivity {
    String response = "";
    EditText LoginEdit;
    EditText PasswordEdit;
    DBTalker dbTalker = new DBTalker();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_actvt);
        LoginEdit = findViewById(R.id.MALoginText);//magic
        PasswordEdit = findViewById(R.id.MAPasswordText);
   }
    Thread getRequest = new Thread() {
        String request;
        @Override
        public void run() {
                request = dbTalker.doesUserExists(MainActvt.this.LoginEdit.getText().toString(),
                        MainActvt.this.PasswordEdit.getText().toString());
                while (!interrupted()) {
                    MainActvt.this.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (request.equals("1")) {
                                Toast.makeText(MainActvt.this, "Вы успешно вошли.", Toast.LENGTH_SHORT).show();
                                getRequest.interrupt();
                            } else if (request.equals("0")) {
                                Toast.makeText(MainActvt.this, "Неверное имя пользователя или пароль.", Toast.LENGTH_SHORT).show();
                            }
                            else {
                                Toast.makeText(MainActvt.this, "Произошла ошибка.", Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
    public void OnMALoginButtonClick(View v) {
        if (LoginEdit.getText().toString().equals("") || PasswordEdit.getText().toString().equals("")) {
            Toast.makeText(MainActvt.this, "Заполните все поля.", Toast.LENGTH_SHORT).show();
        } else {
            if (getRequest.getState() == Thread.State.NEW) {
                getRequest.start();
            }
            else {
                getRequest.notify();
                }
            }
        }
    }
Подскажите пожалуйста. каким все же образом я могу реализовать задуманное? На код попрошу не ргуаться, так как новичок, хотя, если конструктивно, то я только за)
Ответ: Повесить на главный поток прогрессБар и не городить всякую фигню.
Про асинк таск гуглить надо было много лет назад.
Вопрос: Возврат данных из потока

День добрый. Скажите пожалуйста: имеется функция которая возвращает Vector<String>. Ее нужно выполнить в отдельном потоке, но так чтобы потом я мог использовать возвращаеое значение в MainActivity. Как это реализовать?
Ответ: Baron Rojo, привет. Обратные вызовы. Или внутри потока по окончании его работы напишите что-то типа runOnUiThread(new Runnable(...){ ... }); а уже внутри пропишите действия, которые должны выполниться после заполнения Vector<String>.
Вопрос: Как вытащить данные из потока. Cant create handler inside thread that has not called Looper.prepare()

В общем столкнулся со следующей неприятной проблемой.
Есть клиент. Он запрашивает у сервера некоторые данные. Сервер эти данные посылает клиенту. Клиент эти данные принимает и продолжает слушать входящие сообщения. Но проблемы начинаются когда я пытаюсь эти данные вытащить из потока в другой класс.
Ошибка при попытке передать данные из потока в datahandler: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

Вот код клиента
Кликните здесь для просмотра всего текста

Код Java(TM) 2 Platform Standard Edition 5.0
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package com.noldorknight.waiterapp;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
 
public class SocketServer {
 
    private Socket socket;
    private static final int SERVERPORT = 11000;
    private static String SERVER_IP = "192.168.2.222";
    String answer;
    private static String cmdtext;
    private static int callerid;
 
   class ClientThread implements Runnable  
   {
       public void run() {
 
            try {  //Здесь мы создаем сокет
               InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
               socket = new Socket(serverAddr, SERVERPORT);
            } catch (UnknownHostException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
           senddata(); //Здесь запускаем функцию для отправки запроса серверу
 
        }
    }
   //////////////////////////////////////// Эта функция вызывается из отдельного класса, 
   ////////////////////////////////////////того самого которому нужно вернуть ответ
   public void setserver (String command, int caller)
   {
       callerid = caller; //это просто чтобы знать из какого класса была вызвана функция(так как их будет много, и                    //////////////////////////каждый с разным запросом)
        cmdtext = command; //это текст запроса
        new Thread(new ClientThread()).start(); //запускаем поток, тот что сверху
   }
 
    private void handledata(String answer) ///эта функция отсылает целевому классу ответ
    {
        Login lgn = new Login();
        lgn.geturdata(answer);
    }
 
   private void senddata() //отсылаем запрос и слушаем ждем ответа
   {
        try {
            String str = cmdtext;
            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
            out.println(str);
            out.flush();
            System.out.println("-------Начинаем прием данных");
            byte[] data = new byte[256];
            while (true) {
                InputStream inp = socket.getInputStream();
                inp.read(data);
                System.out.println("-------Byte data= " + data);
                answer = new String(data, "UTF-8");
                System.out.println("-------String data= " + answer);
              handledata(answer);  ///// ответ от сервера должен быть передан в другой класс 
 
            }
 
            }
        catch (UnknownHostException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}


Насколько я понял передача данных должна быть в том же потоке, в котором исполняется целевой класс. Как с этим бороться? Мне нужно передать эти данные в главный поток? Или же в отдельный поток?

И еще один вопрос. Как вы видите в отдельном потоке создается новый сокет и начинается обмен данными. Если я вызову передачу данных снова, то и сокет создастся новый, что не есть хорошо. мне нужно поместить создание сокета в отдельный поток? Вообще нужен ли отдельный поток для создания сокета?
Ответ: turbanoff, помогите мне, а то у меня тоже ошибка Can't create handler inside thread that has not called Looper.prepare() и не знаю как бороться...
Кликните здесь для просмотра всего текста
Код Java(TM) 2 Platform Standard Edition 5.0
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
public class NewThread implements Runnable {
    Thread thread;
 
    // konstruktor
    public NewThread() {
        // new potok
        thread = new Thread(this, "VKparser");
        thread.start();
    }
 
    public void run() {
        String httpString = "https://api.vk.com/method/users.get?user_id=205387401&v=5.32";
 
        HttpPost httppost = new HttpPost(httpString);
        HttpClient httpclient = new DefaultHttpClient();
 
        HttpResponse response;
 
        String responseBody;
 
        try {
 
            response = httpclient.execute(httppost);
            responseBody = EntityUtils.toString(response.getEntity());
            Log.d("!!!!!!!!!!!!!!!", responseBody);
            try {
                JSONObject jsonobject = new JSONObject(responseBody);
                JSONArray jsonarray = jsonobject.getJSONArray("response");
                jsonobject = jsonarray.getJSONObject(0);
                String name, famil;
                name = jsonobject.getString("first_name");
                famil = jsonobject.getString("last_name");
                Log.d("!!!", name);
                Log.d("!!!", famil);
                try {
                    MainActivity.getInstance().update();
                } catch (NullPointerException e) {
                    e.printStackTrace();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
 
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

а вот код update() в MainActivity
Кликните здесь для просмотра всего текста
Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
public void update() {
        Toast.makeText(getBaseContext(), "YES ", Toast.LENGTH_LONG).show();
    }


кстати у меня вылетает приложение... и вот еще немного ошибок
05-31 00:15:40.998: E/AndroidRuntime(10441): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-31 00:15:40.998: E/AndroidRuntime(10441): at android.os.Handler.<init>(Handler.java:121)
05-31 00:15:40.998: E/AndroidRuntime(10441): at android.widget.Toast$TN.<init>(Toast.java:322)
05-31 00:15:40.998: E/AndroidRuntime(10441): at android.widget.Toast.<init>(Toast.java:91)
05-31 00:15:40.998: E/AndroidRuntime(10441): at android.widget.Toast.makeText(Toast.java:238)
05-31 00:15:40.998: E/AndroidRuntime(10441): at com.example.jsonparser.MainActivity.update(MainActivity.java:24)
05-31 00:15:40.998: E/AndroidRuntime(10441): at com.example.jsonparser.NewThread.run(NewThread.java:52)
05-31 00:15:40.998: E/AndroidRuntime(10441): at java.lang.Thread.run(Thread.java:856)
Вопрос: Таймер и параллельные потоки

Добрый день, сразу оговорюсь, что прошёлся поиском по темам с запросом "таймер", "потоки" и т.д.

Разрабатываю приложение с Canvas и понадобилось использовать таймер обратного отсчёта:


Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
        new CountDownTimer(10000, 1000) {
            public void onTick(long millisUntilFinished) {
                getSeconds = millisUntilFinished / 1000;
                invalidate();
            }
            public void onFinish() {
            }
 
        }.start();
Сам по себе таймер работает отлично, даже когда интервал обновления ставлю до 1-ой миллисекунды.
Но проблема заключается в том, что есть еще обработчик событий: onTouch и они видимо конфликтуют между собой.
При чём чем меньше интервал обновления и чем чаще я вызываю onTouch тем больше вероятность зависания.

PS. Пытался вывести таймер в отдельный поток, но результатов это не принесло... Возможно хромала реализация
Ответ: Многовато, но хотелось в приложении видеть миллисекунды, проблема в том, как обновлять лишь только их, возможно как-то слои использовать в Canvas или что-то в этом духе...
Вопрос: Обновление ProgressBar из основного потока

Здравствуйте!
Итак, имеется долго выполняющийся код [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].
Ответ: kondusov, спасибо! Не то, что я хотел, но лучше вроде и не сделать. Воспользуюсь именно Вашим вариантом.