Search code examples
javaandroidtimer

Android timer not precise


Ok, so, I'm a real beginner with both java and android programming. I'm trying to make a Basketball application for friendly games. Right now I'm making a shotclock that counts from 24 to 0, plays a sound, and is reseted by a button.

public class MainActivity extends Activity {
    private ShotClock shotClock;
    private TextView shotClockTimer;
    private Timer timer = new Timer();
    private Button shotClockReset;
    private final static int interval = 100;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        shotClockTimer = (TextView) findViewById(R.id.shotClock);
        shotClockReset = (Button)findViewById(R.id.shotClockReset);
        shotClock = new ShotClock();
        shotClockReset.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                shotClock.shotClockReset();
            }

        });
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                TimerMethod();
            }

        }, 0, interval);

    }

    private void TimerMethod() {
        this.runOnUiThread(Timer_Tick);
    }

    private Runnable Timer_Tick = new Runnable() {
        public void run() {
            shotClock.advanceClock();
            shotClockTimer.setText(String.format("%.1f",shotClock.getSeconds()));

        }
    };
}

The idea is that I have a timer that goes of every 0.1 seconds and update the clock accordingly. This works fine, the clock counts from 24-0 and resets properly. My issue is that it's not accurate - I tested it with 3 other timers, and it's always a bit slower: by the time other timers reach 0, this one is only at ~1-1.5 seconds left. What can I do to make it more accurate, besides changing the interval in a primitive way? Please, be friendly since I'm new :) Thanks for the help!


Solution

  • That is because of internal scheduling, the scheduler calls this method approximately every 0.1 seconds. However, the system itself is accurate. Use System.currentTimeMillis() to correct this error.

    Android itself is no realtime application, but the system is the most accurate source you can get.

    So programming precise stopwatches for sportsevents for example are no usecase in android ;)

    Just loop and calculate the offset of miliseconds, if the offset is reached, call a method.

    But think about inaccuracy here too. Calculate the offset always with the start-time (1*0.1 seconds, 2*0.1 seconds...), not with the last value, so minimize inaccuracy here.