Следующий код взят из Head First Android. Это приложение для секундомера.
У меня есть несколько вопросов по следующему коду:
Почему он вообще пропускает hander.post()?
Почему первый не работает? Я ожидаю, что текст будет прыгать назад и вперед от «привет» к «чч: мм: сс».
Запускается ли код нормально, и через 1 секунду вызывается postDelay()?
почему это используется в 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
}
});
}
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() выполняется синхронно (и сразу) и имеет тип пустота. Код не скомпилируется, так как постзадержка() ожидает тип Запускаемый, а не пустота.
@lynxx, вы не увидите HH:MM:SS в пользовательском интерфейсе при установке точки останова «После выполнения textView.setText(time)», потому что основной поток остановлен и TextView не может обновить свой макет. Просто создайте логическое значение флага в Activity и установите либо time, либо "hell0" в зависимости от значения флага (не забудьте изменить значение флага в каждом run()). После этого вам все становится ясно.
Вы правы, значение установлено на
HH:MM:SSпослеtextView.setText(time). Но это не обновлено в графическом интерфейсе. Я проверил, добавив точки останова. После выполненияtextView.setText(time)графический интерфейс по-прежнему отображаетHelloo, даже если значение texview установлено наHH:MM:SS.