如何在队列中使用Handler Postdelayed?

How to use Handler Postdelayed in queue?

我有一个情况,我创建了一个按钮和一个这样的函数。

...
public void BtnOnClick(View view) {

    displayMsg();
}

...

private void displayMsg(){
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();

        }
    }, 3000);

}
...

如果我单击按钮一次,Toast 应该会在 3 秒延迟后出现。 但是,如果我快速单击按钮两次或更多次,那么所有 Toast 在 3 秒后同时出现,而每个 Toast 之间没有延迟 3 秒,这并不好。尽管同时点击,但我希望在每次 Toast 出现之间有 3 秒 gap/delay。

有什么解决办法吗?

如果队列中有多个处理程序,则每个处理程序延迟时间在前一个处理程序延迟时间结束后开始。

也许你可以使用 postAtTime:

AtomicLong previous = new AtomicLong(System.currentTimeMillis());

private void displayMsg(){
    handler.postAtTime(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
        }
    }, previous.updateAndGet(operand -> Long.max(operand + 3000, System.currentTimeMillis() + 3000)));
}

您可以对请求进行排队,以确保按一定时间间隔显示祝酒词。

ArrayList<Runnable> requests = new ArrayList<>;
bool inProgress = false;
private void displayMsg(){
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
            inProgress = false;
            if (requests.size() > 0) {
                handler.postDelayed(requests.remove(0), 3000 + Toast.LENGTH_SHORT);
            }
        }
    }
    if (!inProgress) {
        inProgress = true;
        handler.postDelayed(runnable, 3000);
    } else {
        requests.add(runnable);
    }
}

试试这个:

private final Handler handler = new Handler() {

    final int DELAY = 3000;
    final int DELAY_MSG = 1;
    final Queue<Runnable> pendingRunnables = new ArrayDeque<>();

    @Override
    public void dispatchMessage(Message msg) {
        if (msg.what == DELAY_MSG) {
            final Runnable r = pendingRunnables.poll();
            if (r != null) {
                r.run();
                sendEmptyMessageDelayed(DELAY_MSG, DELAY);
            }
        } else {
            pendingRunnables.add(msg.getCallback());
            if (!hasMessages(DELAY_MSG)) {
                sendEmptyMessage(DELAY_MSG);
            }
        }
    }
};

...

// post action
handler.post(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
    }
});