Android处理程序仅使用最后一个setText()更新TextView

时间:2019-06-29 13:35:07

标签: android android-activity textview android-handler

以下代码来自Head First Android。它用于秒表应用程序。

以下代码中我有几个问题:

  1. 代码的运行方式类似于-> OnCreate-> runTimer()(跳过handler.post())-> OnStart-> onResume->返回handler.post()。

为什么它首先跳过hander.post()

  1. 我有两个textView.setText()。但是第一个不起作用。永远是最后一个。我放第二个只是为了看看postDelay()方法之后代码的作用。

为什么第一个不起作用?我希望文本从“ hello”跳到“ hh:mm:ss”。

  1. 那么在执行postdelay()之后的1秒延迟中到底发生了什么。

代码是否开始正常运行,并在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 
                }
    
            });
        }
    

2 个答案:

答案 0 :(得分:1)

handler.postDelayed(this,1000);

这通常在1秒钟后运行您的函数。延迟1秒。

用您的handler编写的代码将在一秒钟后执行。就这样。

答案 1 :(得分:1)

  

为什么它首先跳过hander.post()

它不会被跳过,它将在onResume()返回之后执行。通过与主线程关联的处理程序排队的所有Runnable仅在onResume()返回之后才开始执行。

  

为什么第一个不起作用?

它确实起作用。您只是无法从视觉上看到它,因为两个方法调用textView.setText()几乎同时被调用。

每个run()都会发生以下呼叫顺序:

  • textView.setText(time)
  • 同一个Runnable已与handler.postDelayed(this,1000)发布到队列中。之后立即
  • textView.setText("hell0")被称为
  

为什么第一个不起作用?我希望文本从“ hello”跳到“ hh:mm:ss”。

您应该实现一个额外的逻辑,以便在每次执行run()时在时间“ hell0” 之间进行切换。

例如在标记中创建一个布尔标志,并根据标志值设置时间或“ hell0”(不要忘记在每次执行run()时更改标志值)

  

为什么在postDelay(this,100)中使用它。应该不是this.run()吗?

否,this.run()是同步执行(且立即执行)的,类型为 void 。该代码将无法编译,因为postDelay()需要 Runnable 类型,而不是 void