检查Android handler是否有回调函数。

9
我有一些代码可以设置计时器,但如果用户在计时器正在使用时设置了该计时器,我需要移除运行计时器的可运行对象并重新启动它。 但是当没有处理程序回调可运行对象存在且调用此代码时,它会导致我的应用程序崩溃。 因此,我需要检查处理程序是否在运行,如果是,则终止并重新启动它。 但是,在查阅文档和其他Stackoverflow问题时,我看不到这是否可能。
下面是我的代码,我已在代码周围添加了注释,只有在一个处理程序可运行对象存在时才应执行该代码:
    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();
            }
    }

});

有人能帮我找出一种检查处理程序当前状态的方法吗?

3个回答

5

参考Jay Snayder的回答:

由于存在这样一种情况,即Map.handler.hasMessages(CALLBACK_PRESENT_INTEGER)返回false,即使Map.handler.sendEmptyMessage(CALLBACK_PRESENT_INTEGER)已被调用(我也遇到过),因此使用布尔值来确定处理程序是否具有回调可能更安全。
因此,代码逻辑非常简单,如下所示:

...

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

...

我在一个应用程序中使用这个解决方案,它完美地工作。


4

如果您想在第一次放置回调时发送空消息,然后在处理程序中检查该消息,这样可以表示存在回调。稍后删除该消息也可以类似地用于查看回调是否仍然存在。我没有相关的情况来参考,但是认为至少应该尝试并分享一种可能性。

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

这可能不是最理想的,但如果您可以在使用回调函数的地方访问处理程序,那么这可能是一个潜在的解决方案。不确定是否有直接的方法可以找出。


3

Handler类有一个方法

boolean hasCallbacks(@NonNull Runnable runnable)

检查消息队列中是否存在任何带有回调runnable的待处理消息。该方法自SDK 16开始存在,但在SDK 29之前是隐藏的。

HandlerCompat类为SDK 16+提供了兼容版本的此方法:

boolean hasCallbacks(handler, runnable)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接