Search code examples
androidtimerunnablestopwatchandroid-handler

How to create a slow stopwatch in android?


I want to create a slow stopwatch in android that begins from 1 second. Everything works fine except one thing. I want it to be slow meaning:

1.000/s //Start Time
1.001/s //After 10ms
1.002/s //After another 10ms

It is not a real stopwatch, but it's something like it. I need that for a game I'm creating that increases the time every 10ms. Please test the code on an emulator or a real device for better understanding.

Code:

private void startTime() {

    final long startTime = SystemClock.uptimeMillis();

    timeHandler = new Handler(); //Handler
    timeRunnable = new Runnable() { //Runnable
        @Override
        public void run() {
            long timeInMilliseconds = SystemClock.uptimeMillis() - startTime + 1000; //Start time is 1.000/s
            int secs = (int) (timeInMilliseconds / 1000);
            int mins = secs / 60;
            secs = secs % 60;
            int milliseconds = (int) (timeInMilliseconds % 1000);
            if (timeInMilliseconds > 60000) {
                score.setText(mins + ":" + String.format("%02d", secs) + "." + String.format("%03d", milliseconds) + "/s");
            } else {
                score.setText(String.format("%01d", secs) + "." + String.format("%03d", milliseconds) + "/s");
            }
            timeHandler.postDelayed(this, 0);
        }
    };

    timeHandler.postDelayed(timeRunnable, 0);
}

Note that score is just a normal TextView to show the time. Please help me. Thanks.


Solution

  • After much trial and error, I have found a very simple solution to that, and I will post it here in case someone faces the same problem like me in the future.

    private void startTime() {
    
        final long startTime = SystemClock.uptimeMillis();
    
        timeHandler = new Handler();
        timeRunnable = new Runnable() {
            @Override
            public void run() {
    
                //Note the difference in the first two lines here.
                long timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
                //You can change this 20 according to what you want.
                timeInMilliseconds = (timeInMilliseconds / 20) + 1000;
    
                int secs = (int) (timeInMilliseconds / 1000);
                int mins = secs / 60;
                secs = secs % 60;
                int milliseconds = (int) (timeInMilliseconds % 1000);
                if (timeInMilliseconds > 60000) {
                    score.setText(mins + ":" + String.format("%02d", secs) + "." + String.format("%03d", milliseconds) + "/s");
                } else {
                    score.setText(String.format("%01d", secs) + "." + String.format("%03d", milliseconds) + "/s");
                }
                timeHandler.postDelayed(timeRunnable, 0);
            }
        };
    
        timeHandler.postDelayed(timeRunnable, 0);
    }
    

    Now, the stopwatch speed rate has been decreased. I made the time increase 1ms every 20ms instead of 10ms as I mentioned in the question before because that was more suitable for me. Of course you can change this 20 to anything you want.