3

I am using Java executorservice to create a timeout effect in one of my apps. After an elapsed time, they executor service begins and logs the user out of their session. But on an Android device when the device goes to sleep the executor thread is suspended. After the device awakes the thread is unsuspended. I would like the change the clock the executor is using so that it continues counting even after the device goes to deep sleep. Is there no way I can over ride which clock is being used (I realize I can swap out the entire implementation and use alarmmanager but I'm looking to not alter existing code at this point so please do not try to offer other APIs).

My question is, there must be a system clock that keeps going despite the device being asleep, how can I let the executor scheduler use that clock instead of the one it's using now which respects the device going to deep sleep and pauses ticking?

My code I have currently is very simple and just looks like this:

myExecutorService.schedule(new EndUserSession(),
                        6L, TimeUnit.MINUTES);

this code above starts the EndUserSession() in 6 minutes. It works but I want to use another clock that does not respect time out of mobile device.

Nayuki
  • 17,911
  • 6
  • 53
  • 80
j2emanue
  • 60,549
  • 65
  • 286
  • 456

1 Answers1

2

I have strong doubts that it's possible to influence scheduler service timing mechanisms.

You have another option to avoid problems caused by device sleep, like passing specific timestamp in constructor and scheduling a task at fixed rate. Example:

class EndSessionTask {

    final long sessionExpirationTime;
    volatile ScheduledFuture future;

    public EndSessionTask(long ts) { sessionExpirationTime = ts; }

    public void run() {
        if (sessionExpirationTime < currentTs) return;
        endSession();
        future.cancel();
    }

    public void setFuture(ScheduledFuture f) { this.future = f; }
}

long endSessionTime = System.currentTimeMillis() + 6 * 60 * 1000;
EndSessionTask task = new EndSessionTask(endSessionTime);
ScheduledFuture future = executorService.scheduleAtFixedRate(task, 10L, 10L, SECONDS);
task.setFuture(future);
AdamSkywalker
  • 11,408
  • 3
  • 38
  • 76
  • Can you explain the 10L logic. If not clear how this helps. Device can go to sleep and your schedule will freeze. When it awakes it still continues were it left off – j2emanue Feb 28 '16 at 13:52
  • @j2emanue the idea is to check if session expired every 10 seconds. If device sleeps for an hour, the task will trigger in 10 seconds after wakeup. It will notice that expiration time has already passed and kill the session. Then it will cancel scheduled task. – AdamSkywalker Feb 28 '16 at 15:29