处理程序无法正常工作
Handler doesn't work correctly
首先,如果我的标题没有很好地描述我的问题,但我找不到更好的标题,请原谅。
有一个简单的秒表应用程序,它具有启动、停止、重置三个按钮和一个显示时间的文本视图。应用只有一个 activity 这样的:
public class StopwatchActivity extends AppCompatActivity {
private int mNumberOfSeconds = 0;
private boolean mRunning = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stopwatch);
//if if uncomment this runner method and delete the runner inside onClickStart everything will work find
//runner()
}
public void onClickStart(View view){
mRunning = true;
runner();
}
public void onClickStop(View view){
mRunning = false;
}
public void onClickReset(View view){
mRunning = false;
mNumberOfSeconds = 0;
}
public void runner(){
final TextView timeView = (TextView) findViewById(R.id.time_view);
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
int hours = mNumberOfSeconds/3600;
int minutes = (mNumberOfSeconds%3600)/60;
int second = mNumberOfSeconds%60;
String time = String.format("%d:%02d:%02d" , hours , minutes , second );
timeView.setText(time);
if (mRunning){
mNumberOfSeconds++;
}
handler.postDelayed(this , 1000);
}
});
}
}
我的问题是当我在 onClickStart 方法中注释 runner() 并将其放入 onCreate 方法时一切正常。但是当我像上面那样更改代码时,代码仍然是 运行 但是在我按下停止按钮然后再次按下开始之后,第二个将非常快地增加 4 或 5。
谁能解释一下这两种模式有什么区别?
全局声明你的处理程序
public void runner(){
timeView = (TextView) findViewById(R.id.time_view);
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
int hours = mNumberOfSeconds/3600;
int minutes = (mNumberOfSeconds%3600)/60;
int second = mNumberOfSeconds%60;
String time = String.format("%d:%02d:%02d" , hours , minutes , second );
timeView.setText(time);
if (mRunning){
mNumberOfSeconds++;
}
handler.postDelayed(this , 1000);
}
}
handler.post(runnable);
}
在按钮函数中
public void onClickStart(View view){
if(handler != null) {
//restart the handler to avoid duplicate runnable
handler.removeCallbacks(runnable);//or this handler.removeCallbacksAndMessages(null);
}
mRunning = true;
runner();
}
public void onClickStop(View view){
mRunning = false;
handler.removeCallbacks(runnable); // this will stop the handler from working
}
首先,如果我的标题没有很好地描述我的问题,但我找不到更好的标题,请原谅。
有一个简单的秒表应用程序,它具有启动、停止、重置三个按钮和一个显示时间的文本视图。应用只有一个 activity 这样的:
public class StopwatchActivity extends AppCompatActivity {
private int mNumberOfSeconds = 0;
private boolean mRunning = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stopwatch);
//if if uncomment this runner method and delete the runner inside onClickStart everything will work find
//runner()
}
public void onClickStart(View view){
mRunning = true;
runner();
}
public void onClickStop(View view){
mRunning = false;
}
public void onClickReset(View view){
mRunning = false;
mNumberOfSeconds = 0;
}
public void runner(){
final TextView timeView = (TextView) findViewById(R.id.time_view);
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
int hours = mNumberOfSeconds/3600;
int minutes = (mNumberOfSeconds%3600)/60;
int second = mNumberOfSeconds%60;
String time = String.format("%d:%02d:%02d" , hours , minutes , second );
timeView.setText(time);
if (mRunning){
mNumberOfSeconds++;
}
handler.postDelayed(this , 1000);
}
});
}
}
我的问题是当我在 onClickStart 方法中注释 runner() 并将其放入 onCreate 方法时一切正常。但是当我像上面那样更改代码时,代码仍然是 运行 但是在我按下停止按钮然后再次按下开始之后,第二个将非常快地增加 4 或 5。 谁能解释一下这两种模式有什么区别?
全局声明你的处理程序
public void runner(){
timeView = (TextView) findViewById(R.id.time_view);
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
int hours = mNumberOfSeconds/3600;
int minutes = (mNumberOfSeconds%3600)/60;
int second = mNumberOfSeconds%60;
String time = String.format("%d:%02d:%02d" , hours , minutes , second );
timeView.setText(time);
if (mRunning){
mNumberOfSeconds++;
}
handler.postDelayed(this , 1000);
}
}
handler.post(runnable);
}
在按钮函数中
public void onClickStart(View view){
if(handler != null) {
//restart the handler to avoid duplicate runnable
handler.removeCallbacks(runnable);//or this handler.removeCallbacksAndMessages(null);
}
mRunning = true;
runner();
}
public void onClickStop(View view){
mRunning = false;
handler.removeCallbacks(runnable); // this will stop the handler from working
}