Search code examples
javaandroidservicetimersleep

Periodic timertask executed several times at once after Android returns from sleep


I've implemented a background service to update data in my app periodically. The mechanism works well if my android device is turned on but causing issues when Android is in sleep mode:

Let's imagine the service is running every 15 minutes, then Android goes to sleep for 1 hour and when weaking up again, the service will be executed 4 times at once. The prefered bahaviour would be running the service once only, in case it missed 1 or more cycles due to sleep.

To run my code periodically, I'm using TimerTask:

public class updateService extends IntentService {

public int onStartCommand(@Nullable Intent intent, int flags, int startId) {

        if(mTimer != null) {
            mTimer.cancel();
        }
        mTimer = new Timer();

        int timer = getPreference("refresh_interval") * 1000;
        mTimer.scheduleAtFixedRate(new updateTask (), timer, timer);
        return super.onStartCommand(intent, flags, startId);
    }

    class updateTask extends TimerTask {

        @Override
        public void run() {
            // run on another thread
            mHandler.post(new Runnable() {

                @Override
                public void run() {
                   // Do job
                }
            });
        }   
}
}

I'd appreciate any suggestions how to do better. Thanks!


Solution

  • You are using Timer.scheduleAtFixedRate(TimerTask task, long delay, long period) which explains in its documentation:

    If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up."

    It seems you want to use Timer.schedule(TimerTask task, long delay, long period) instead, which says:

    If an execution is delayed for any reason (such as garbage collection or other background activity), subsequent executions will be delayed as well.