英文:
handler.postDelayed not working correctly
问题
我有一个简单的秒表代码片段。线程在自定义类中运行,它通过接口连接到主活动
public class MainActivity extends AppCompatActivity implements MainActivityInteractionInterface{
public static boolean isRunning = false;
Stopwatch stopWatch;
private TextView textViewMilliSeconds;
private TextView textViewSeconds;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textViewMilliSeconds = findViewById(R.id.textViewStopwatchMilliseconds);
    textViewSeconds = findViewById(R.id.textViewStopwatchSeconds);
    stopWatch = new Stopwatch(this, getApplicationContext());
    stopWatch.runThread();
}
@Override
public void updateUI() {
    String time = String.format(Locale.getDefault(), "%03d", stopWatch.getMilliseconds());
    textViewMilliSeconds.setText(time);
    String timeSeconds = String.format(Locale.getDefault(), "%02d", stopWatch.getSeconds());
    textViewSeconds.setText(timeSeconds);
}
public void startTimer(View view) {
    isRunning = !isRunning;
}
}
public class Stopwatch {
private int milliseconds = 0;
private int seconds = 0;
public int getMilliseconds() {
    return milliseconds;
}
public int getSeconds() {
    return seconds;
}
private MainActivityInteractionInterface interactionInterface;
private Context applicationContext;
public Stopwatch(MainActivityInteractionInterface interactionInterface, Context applicationContext){
    this.interactionInterface = interactionInterface;
    this.applicationContext = applicationContext;
}
public void runThread(){
    final Handler handler = new Handler();
    handler.post(new Runnable(){
        @Override
        public void run(){
            if(isRunning) {
                milliseconds++;
                if (milliseconds == 1000) {
                    milliseconds = 0;
                    seconds++;
                    if(seconds == 60){
                        seconds = 0;
                    }
                }
            }
            interactionInterface.updateUI();
            handler.postDelayed(this, 1);
        }
    });
}
}
处理程序应该每1毫秒更新一次,在达到1000毫秒时,经过1秒。如果我设置handler.postDelayed延迟低于15,达到1000毫秒将需要确切的18秒,为什么?
英文:
I have a simple stopwatch code piece. Thread is running in custom class, it connects to the main activity via Interface
public class MainActivity extends AppCompatActivity implements MainActivityInteractionInterface{
public static boolean isRunning = false;
Stopwatch stopWatch;
private TextView textViewMilliSeconds;
private TextView textViewSeconds;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textViewMilliSeconds = findViewById(R.id.textViewStopwatchMilliseconds);
    textViewSeconds = findViewById(R.id.textViewStopwatchSeconds);
    stopWatch = new Stopwatch(this, getApplicationContext());
    stopWatch.runThread();
}
@Override
public void updateUI() {
    String time = String.format(Locale.getDefault(), "%03d", stopWatch.getMilliseconds());
    textViewMilliSeconds.setText(time);
    String timeSeconds = String.format(Locale.getDefault(), "%02d", stopWatch.getSeconds());
    textViewSeconds.setText(timeSeconds);
}
public void startTimer(View view) {
    isRunning = !isRunning;
}
public class Stopwatch {
private int milliseconds = 0;
private int seconds = 0;
public int getMilliseconds() {
    return milliseconds;
}
public int getSeconds() {
    return seconds;
}
private MainActivityInteractionInterface interactionInterface;
private Context applicationContext;
public Stopwatch(MainActivityInteractionInterface interactionInterface, Context applicationContext){
    this.interactionInterface = interactionInterface;
    this.applicationContext = applicationContext;
}
public void runThread(){
    final Handler handler = new Handler();
    handler.post(new Runnable(){
        @Override
        public void run(){
            if(isRunning) {
                milliseconds++;
                if (milliseconds == 1000) {
                    milliseconds = 0;
                    seconds++;
                    if(seconds == 60){
                        seconds = 0;
                    }
                }
            }
            interactionInterface.updateUI();
            handler.postDelayed(this, 1);
        }
    });
}
handler should update every 1 millisec, when there is 1000 milliseconds, 1 second passes by
If I set handler.postDelayed delay anything below 15 reaching 1000 milliseconds would take exactly 18 seconds, why?
答案1
得分: 1
我不知道为什么需要长达18秒的时间,但我可以告诉你这个:Android每16毫秒刷新一次UI(以达到60fps的速率),所以在更短的时间内将处理程序设置为updateUI没有意义,而且可能还会干扰它。
依我拙见,将其更新间隔设置为20毫秒,并相应地更改计数器的值,如下所示:
handler.post(new Runnable(){
    @Override
    public void run(){
        if(isRunning) {
            milliseconds++;
            if (milliseconds == 50) {
                milliseconds = 0;
                seconds++;
                if(seconds == 60){
                    seconds = 0;
                }
            }
        }
        interactionInterface.updateUI();
        handler.postDelayed(this, 20);
    }
});
英文:
I don't know why it would take up to 18seconds, but I can tell you this: Android refresh the UI every 16msec (to have a rate of 60fps), so setting the handler to updateUI in a lesser time would make no sense and maybe also interfier with it.
In my humble opinion, make it to update in 20msec and change the counter values according, like this:
handler.post(new Runnable(){
    @Override
    public void run(){
        if(isRunning) {
            milliseconds++;
            if (milliseconds == 50) {
                milliseconds = 0;
                seconds++;
                if(seconds == 60){
                    seconds = 0;
                }
            }
        }
        interactionInterface.updateUI();
        handler.postDelayed(this, 20);
    }
});
答案2
得分: 0
看看 handler.postDelayed(this, 1); 的第二个参数。
根据你增加毫秒的方式进行修改。
英文:
Look at the second argument of handler.postDelayed(this, 1);
Change it according to the way you increment your milliseconds.
专注分享java语言的经验与见解,让所有开发者获益!

评论