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

标签 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。不应该是 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 
                }
    
            });
        }
    

最佳答案

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".

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

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

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

不,this.run() 是同步(并立即)执行的,并且是 void 类型。代码不会编译为 postDelay()需要 Runnable 类型,而不是 void

关于Android 处理程序仅使用最后一个 setText() 更新 TextView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56817960/

相关文章:

android - C++ - 将结构转换为字符

Android:使用 singleTop 或 SingleTask 恢复 Activity

android - 全局捕获某些 Activity 中抛出的异常

ios - 如何让 UITextView 键盘不会通过点击而关闭_Swift

android - 在eclipse中添加库项目出错

java - 如何将 Android Wear Activity 类导入移动 Activity 类?

android - 测量文本问题的宽度

java - Android - TextView 与 Listview 一起滚动/在 Listview 之前滚动

android - 在 Android 上有一个初始化脚本,可以在定义的 URL 上启动浏览器全屏吗?

android - 从服务中获取当前 Activity 引用