2

I have a webpage that retrieves the GPS positions of buses, and display those in a map. It retrieves the positions once every 60 seconds through a loop like this:

function startLinhaLoop() {
  if (!timer) {
    loopLinha();
    timer = setInterval(function() {loopLinha()}, 60000);
  }
}

It works perfectly, you can see it working here.

I put the whole thing in an app for android, that I use regularly. One of its features is that, if the screen of the phone is off, it speaks how long the 3 closest buses will take to arrive. So, once each 60 seconds, you hear "Buses in x, y, and z seconds". The web version also speaks if the page is not active.

This app always worked perfectly, as the webpage. But in the last two months (after I updated Android Studio) it began to fail (no idea why): the loop takes much longer than 60 secs, and it is even irregular. It speaks now, then 3 minutes later, then 8, then 2, then 12... I have tried to see what happens, and the script is not getting stalled, nor waiting for a download (the download has a timeout). It is simply like instead of timeout 60000 it was timeout random.

But the really strange phenomena happens when I try to debug the app: as soon as I connect adb wireless and begin looking at adb logcat, the timer works perfectly. I stop adb server, and the timer goes crazy again. Connect, fine. Disconnect, crazy... It is like the timer knows that I am looking to it. A Schrodinger timer. :) During all the time, the wifi is connected and the phone makes noises when receiving whatsapp or whatever, so internet is fully active always.

I know that this question is not very specific and kind of vague (sorry for that), but maybe someone has heard of something like this before. Maybe this is a bug in some recent release of Android Studio?

BTW, I am working in a rooted Android 4.4 in a Galaxy Note 4. In my wife phone it works as expected.

Luis A. Florit
  • 2,169
  • 1
  • 33
  • 58
  • I think for a perfect solution, you should convert it into native java... – Jonas Wilms Dec 25 '16 at 17:05
  • Clear the timer when the window loses focus.. see http://stackoverflow.com/questions/7479305/event-for-browser-tab-hidden-shown – Mottie Dec 25 '16 at 17:08
  • @Jonasw: No way. It's a 900 page javascript. And, more importantly, I don't want to maintain two separate codes. That's a road to disaster. – Luis A. Florit Dec 25 '16 at 17:22
  • 2
    Yeah, but android goes to sleep (and wakes up sometimes), you need to control this wakeup to get the desired behaviour... – Jonas Wilms Dec 25 '16 at 17:24
  • @Jonasw: I don't think it is a wakeup thing, since I get whatsapp noises all the time while the app should be responding. And with tasker I set `Sleep never` while at home. – Luis A. Florit Dec 25 '16 at 17:29
  • 2
    Yeah, whatsapp wakes up, doeant mean that your js is running... – Jonas Wilms Dec 25 '16 at 17:30
  • @Mottie: you mean to do a `clearTimeout(timer)`? – Luis A. Florit Dec 25 '16 at 18:04
  • Yes, but you're using `setInterval`, so stop it using [`clearInterval`](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval). – Mottie Dec 25 '16 at 18:05
  • @Mottie: I'm not sure what you mean. If I `clearInterval`, the timer loop just stops. You mean to restart the whole thing? – Luis A. Florit Dec 25 '16 at 18:23
  • Clear the interval when the tab loses focus, then restart the interval when focus is regained; unless you want the app to keep talking... – Mottie Dec 25 '16 at 18:37
  • @Mottie: Yes, this is exactly what I want: when the screen is off, I want it to keep talking to me. Sorry if I wasn't clear enough. – Luis A. Florit Dec 25 '16 at 18:38
  • 1
    Maybe this answer will help... http://stackoverflow.com/a/12522580/145346 – Mottie Dec 25 '16 at 18:41
  • @Mottie: Thanks, since the web version is working fine, I solved the thing with a `wakelock` (see my answer). But I will take your suggestion into account, I didn't know about `WebWorker`. Thanks! – Luis A. Florit Dec 26 '16 at 01:01

1 Answers1

0

I solved this by using a wakelock in the pure java part of my code:

PowerManager pm;
PowerManager.WakeLock wakeLock;

public void onCreate(final Bundle onOreintChange) {
    pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag");
    wakeLock.acquire();
    ....

and (not sure if this is necessary, just in case)

public void onDestroy() {
    super.onDestroy();
    wakeLock.release();
    ...

For some reason that I don't understand, this was not needed before and now it is in my Android 4.4 (still not needed in my wife's Android 6.0). Certainly adb prevents the device sleep, that's why it worked fine during the debug. In other projects I tried wakelock before, but never worked as I expected.

Although I did not follow @Jonas w advice above exactly as he proposed, it made me give wakelock another try. Thanks Jonas!

Luis A. Florit
  • 2,169
  • 1
  • 33
  • 58