以下代码来自 Head First Android。它适用于秒表应用程序。
我在下面的代码中有几个问题:
- 代码运行方式为 -> OnCreate -> runTimer()(跳过 handler.post()) -> OnStart -> onResume -> 返回到 handler.post()。
为什么它首先跳过 hander.post()
?
- 我有两个 textView.setText()。但是第一个不起作用。永远是最后一个。我放第二个只是为了看看代码在 postDelay() 方法之后做了什么。
为什么第一个不起作用?我希望文本从“hello”到“hh:mm:ss”来回跳转。
- 那么在执行 postdelay() 后的 1 秒延迟期间究竟发生了什么。
代码是否开始正常运行,并在 1 秒时调用 postDelay()?
为什么在 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/