Обработчик Android обновляет TextView только с последним setText()

Следующий код взят из Head First Android. Это приложение для секундомера.

У меня есть несколько вопросов по следующему коду:

  1. Код работает как -> OnCreate -> runTimer() (пропускает handler.post()) -> OnStart -> onResume -> Возвращается к handler.post().

Почему он вообще пропускает hander.post()?

  1. У меня есть два textView.setText(). Но первый не работает. Он всегда последний. Я поставил второй, чтобы посмотреть, что делает код после метода postDelay().

Почему первый не работает? Я ожидаю, что текст будет прыгать назад и вперед от «привет» к «чч: мм: сс».

  1. Итак, что именно происходит во время 1-секундной задержки после выполнения postdelay().

Запускается ли код нормально, и через 1 секунду вызывается postDelay()?

  1. почему это используется в postDealy(this, 100). не должно быть this.run()?

    public class MainActivity extends AppCompatActivity {       
        private boolean running = false;
        private int counter = 0;
        private Handler handler = new Handler();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            runTimer();
        }
    
        public void onClickStart(View view){
            running = true;
        }
    
        public void runTimer(){
            final TextView textView = findViewById(R.id.timer);
    
            handler.post(new Runnable() {
    
                @Override
                public void run() {
                    int hours = counter/3600;
                    int minutes = (counter%3600)/60;
                    int secs = counter%60;
    
                    String time = String.format("%d:%02d:%02d", hours, minutes, secs);
                    textView.setText(time); // Doesn't set it to this - see last line 
    
                    if (running){
                        counter++;
                    }
                    handler.postDelayed(this,1000); // what does happens between next one second 
                    textView.setText("hell0"); // Always set it to this 
                }
    
            });
        }
    
1
0
558
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

handler.postDelayed(this,1000);

Это использовалось для запуска вашей функции через 1 секунду. Это задержка на 1 секунду.

Код, написанный в вашем handler, выполнится через секунду. Это все.

Ответ принят как подходящий

Why does it skip hander.post() in the first place?

Он не пропускается, он будет выполнен после возврата onResume(). Все Runnable, поставленные в очередь через обработчик, связанный с основным потоком, начинают свое выполнение только после возврата onResume().

Why doesn't the first one work?

Это работает. Вы просто не можете увидеть это визуально, потому что вызовы двух методов textView.setText() вызываются «почти» одновременно.

На каждом run() происходит следующая последовательность вызовов:

  • textView.setText(time),
  • тот же Runnable ставится в очередь с handler.postDelayed(this,1000). Сразу после этого
  • textView.setText("hell0") называется

Why doesn't the first one work? I am expecting the text to jump back and forth from "hello" to "hh:mm:ss".

Вы должны реализовать дополнительную логику для переключения между время и "ад0" при каждом выполнении run().

Например. создайте логический флаг в Activity и установите либо время, либо «hell0» в зависимости от значения флага (не забывайте менять значение флага при каждом выполнении run()).

why is this used in postDelay(this, 100). shouldn't it be this.run()?

Нет, this.run() выполняется синхронно (и сразу) и имеет тип пустота. Код не скомпилируется, так как постзадержка() ожидает тип Запускаемый, а не пустота.

Вы правы, значение установлено на HH:MM:SS после textView.setText(time). Но это не обновлено в графическом интерфейсе. Я проверил, добавив точки останова. После выполнения textView.setText(time) графический интерфейс по-прежнему отображает Helloo, даже если значение texview установлено на HH:MM:SS.

lynxx 29.06.2019 17:27

@lynxx, вы не увидите HH:MM:SS в пользовательском интерфейсе при установке точки останова «После выполнения textView.setText(time)», потому что основной поток остановлен и TextView не может обновить свой макет. Просто создайте логическое значение флага в Activity и установите либо time, либо "hell0" в зависимости от значения флага (не забудьте изменить значение флага в каждом run()). После этого вам все становится ясно.

Onik 29.06.2019 17:43

Другие вопросы по теме