Search code examples
androidpostdelayed

Why charging state of the phone affects my app's behavior


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
                    ...
                    ...
            }
        }
    }

Solution

  • 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 :)