Android 处理程序仅使用最后一个 setText() 更新 TextView
Android Handler updates TextView only with last setText()
以下代码来自 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.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()
returns之后执行。所有 Runnable
s,通过与主线程关联的处理程序排队,仅在 onResume()
returns.
之后开始执行
Why doesn't the first one work?
确实有效。您只是无法直观地看到它,因为两个方法调用 textView.setText()
同时被调用 "almost"。
以下调用顺序发生在每个 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 中创建一个布尔标志,并根据标志值设置时间或 "hell0"(不要忘记在每次 run()
执行时更改标志值) .
why is this used in postDelay(this, 100). shouldn't it be this.run()
?
不,this.run()
是同步(并且立即)执行的,类型是void。代码不会编译,因为 postDelay() 需要 Runnable 类型,而不是 void.
以下代码来自 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.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()
returns之后执行。所有 Runnable
s,通过与主线程关联的处理程序排队,仅在 onResume()
returns.
Why doesn't the first one work?
确实有效。您只是无法直观地看到它,因为两个方法调用 textView.setText()
同时被调用 "almost"。
以下调用顺序发生在每个 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 中创建一个布尔标志,并根据标志值设置时间或 "hell0"(不要忘记在每次 run()
执行时更改标志值) .
why is this used in postDelay(this, 100). shouldn't it be
this.run()
?
不,this.run()
是同步(并且立即)执行的,类型是void。代码不会编译,因为 postDelay() 需要 Runnable 类型,而不是 void.