Check if Android handler has callbacks

10,762

Solution 1

If you want you could send an empty message when you first put a callback in and then check for that message in the handler. This empty message could represent that there is a callback present. Removing that message later could then be used similarly to see if the callback is still there. Don't have a relevant situation such as this to go from, but thought that I would at least try and share a possibility.

...
Map.handler.sendEmptyMessage(CALLBACK_PRESENT_INTEGER);
...
if(Map.handler.hasMessages(CALLBACK_PRESENT_INTEGER)
...
Map.handler.removeMessage(CALLBACK_PRESENT_INTEGER);
...

This is probably not ideal, but could be a potential solution if you have access to your handler from the point where your callback is used. Not sure if there is a direct way to find out.

Solution 2

Referring to Jay Snayder's reply:

Since there are cases in which Map.handler.hasMessages(CALLBACK_PRESENT_INTEGER) returns false even though Map.handler.sendEmptyMessage(CALLBACK_PRESENT_INTEGER) has been called (happened to me, too), it may be safer to use a boolean to determine whether the handler has callbacks or not.
So, the code logic is something very simple like this:

...

boolean callbackPresent = false;

...

if(!callbackPresent) {

    // do what you have to do in case the handler doesn't have callbacks

    // right before adding a callback to the handler, call:
    callbackPresent = true;

} else {

    // do what you have to do in case the handler has callbacks

    // right before removing the callbacks from the handler, call:
    callbackPresent = false;
}

...

I'm using this solution in an app and it's working perfectly.

Solution 3

Handler class has a method

boolean hasCallbacks(@NonNull Runnable runnable)

to check if there are any pending posts of messages with callback runnable in the message queue.
It exists since SDK 16 but it's hidden prior to SDK 29.

HandlerCompat class has the compatible version of this method for SDKs 16+:

boolean hasCallbacks(handler, runnable)
Share:
10,762
deucalion0
Author by

deucalion0

I am a student studying Computing Science.

Updated on June 10, 2022

Comments

  • deucalion0
    deucalion0 almost 2 years

    I have some code which sets a timer, but if a user sets the timer while it is in use I need to remove the runnable which runs the timer and start it again. But when no handler callback runnable exists and this code is called it crashes my application. So I need to check if a handler is running, if so then end it and restart it, but looking through the documentation and other Stackoverflow questions, I cannot see if this is possible.

    Here is my code, I have commented around the code which should only be executed if a handler runnable exists:

        submitTimer.setOnClickListener(new View.OnClickListener(){
    
            public void onClick(View v) {
                String s = timer.getText().toString();
                if(!s.equals(""))
                {
    //I NEED TO CHECK A RUNNABLE HANDLER EXISTS AND IF SO THEN RUN THIS CODE, IF NOT IGNORE THIS CODE
                Map.handler.removeCallbacks(Map.getRunnable());
                Map.runnable.run();
    //I NEED TO CHECK A RUNNABLE HANDLER EXISTS AND IF SO THEN RUN THIS CODE, IF NOT IGNORE THIS CODE
                int l = Integer.parseInt(s);
                Map.timerinmins = l;
                timer.setHint("Current Timer is "+Map.timerinmins);
                timer.setText("");
                Toast.makeText(Preferences.this, "Timer is set!", Toast.LENGTH_SHORT).show();
                }
    
                else
                {
    
                    Toast.makeText(Preferences.this, "No value was entered", Toast.LENGTH_SHORT).show();
                }
        }
    
    });
    

    Can anyone help me figure out a way of checking the handlers current state?