1

I have a Runnable r that is triggered periodically once per minute by handler.postDelayed(60*1000). And I test my code on a real device.

However I notice, when the phone is charging (AC or USB) , it works well, but if the phone is disconnected, the Runnable r will only run once every 20min or even worse, several hours. Thanks for any help!

Below is the code:

private final Runnable listen_to_server = new Runnable(){
    public void run(){
        new Thread() {
            public void run() {
                try {

                    handler.sendMessage(handler.obtainMessage(PING_SERVER,"listen"));
                    synchronized (listen) {
                        listen.wait();
                    }
                    handler.postDelayed(listen_to_server, 50000);
                }
                catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }.start();
    }
};

In the Handler:

    handler=new Handler() {
        @Override
        public void handleMessage(final Message msg) {
            switch (msg.what) {
                case PING_SERVER:
                    String type = (String) msg.obj;
                    add_log("ping server"); // print to screen and Log.d
                    ...
                    ...
            }
        }
    }
Zhang Yifan
  • 233
  • 1
  • 2
  • 7
  • post your runnable code and how you are calling it – karan Aug 26 '15 at 07:32
  • can you post some code please? – Pier Giorgio Misley Aug 26 '15 at 07:33
  • Your phone probably goes into deep sleep mode to save battery when it's not connected via USB and the screen is off. AFAIK timers won't be updated at all / not as often while in deep sleep. – Michael Aug 26 '15 at 07:37
  • possible duplicate of [Will a Handler postDelayed not being fired when CPU sleeps?](http://stackoverflow.com/questions/17324587/will-a-handler-postdelayed-not-being-fired-when-cpu-sleeps) – Michael Aug 26 '15 at 07:41
  • @Michael Maybe this is the case, but how could I solve this problem. I do not want it go to sleep – Zhang Yifan Aug 26 '15 at 07:42
  • @Michael Is there a way (by code) that I can prevent my phone from sleeping, or pretend that it is charging? – Zhang Yifan Aug 26 '15 at 07:43

1 Answers1

1

Referring to this link i think the problem might be, as they said:

Android is not a real-time operating system. All postDelayed() guarantees is that it will be at least the number of milliseconds specified. Beyond that will be dependent primarily on what the main application thread is doing (if you are tying it up, it cannot process the Runnable), and secondarily on what else is going on the device (services run with background priority and therefore get less CPU time than does the foreground).

How to fix this? in this post the solution was the following:

You'll probably have better luck using the AlarmManager for such a long delay. Handler is best for ticks and timeouts while your app is in the foreground.

so try implement an AlarmManager looking at the doc.

Hope i helped :)

Community
  • 1
  • 1
Pier Giorgio Misley
  • 5,305
  • 4
  • 27
  • 66
  • Thanks for the link. But my app is indeed in foreground -- I have even killed all other apps -- and I wish to leave my app on for hours, with the runnable runs once per minute – Zhang Yifan Aug 26 '15 at 07:48
  • @ZhangYifan You tryed using a service? – Pier Giorgio Misley Aug 26 '15 at 07:52
  • anyway, not sure, but is it correct the Runnable's syntax? i think before Run you need @Override and after it you don't need the "new Thread(){". Maybe i'm wrong, don't know – Pier Giorgio Misley Aug 26 '15 at 07:56
  • Maybe i will try using a service later... I need new Thread() in runnable as it needs to do network stuff which could not be on the main thread. Thanks for the @Override :) but that seems not mandated. – Zhang Yifan Aug 26 '15 at 08:30
  • @ZhangYifan sorry but i don't know what else to do, maybe someone can help you more :) – Pier Giorgio Misley Aug 26 '15 at 08:40