如何在队列中使用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();
}
});
我有一个情况,我创建了一个按钮和一个这样的函数。
...
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();
}
});