当尝试学习如何创建延迟时,我研究并发现主要答案是使用 Handler/Runnable/postDelayed。
Handler handler=new Handler();
final Runnable r = new Runnable()
{
public void run()
{
delayedMethod();
}
};
handler.postDelayed(r, 1000);
一段时间以来,这工作得很好,但我又添加了一些正在进行的事情,现在它们有时会以错误的顺序发生。
本组活动:
画屏1()
...
延迟绘制屏幕2()
...
画屏3()
搞砸了(有时)并这样做:
画屏1()
...
画屏3()
...
延迟PaintScreen2()(最后运行并被paintScreen3的操作弄乱)
似乎没有另一种创建延迟的好方法 - 一种不创建线程的方法。
为了确保代码事件以正确的顺序运行,我尝试过的解决方案:
0 将主进程放在一个大的同步块中。
1 在主流程涉及的每个方法的方法名中放入synchronized关键字。
2 仅将synchronized关键字放在Runnable中的方法上。
3 去掉 Handler/Runnable/postdelayed 并替换为 handler.sendEmptyMessageDelayed(0,1000)
4 创建一个 Handler 实例变量,供每个 Handler/Runnable 块使用(而不是 Handler handler1、handler2、handler3 等)
5
Handler handler=new Handler();
final Runnable r = new Runnable()
{
public void run()
{
waitOver = true;
}
};
handler.postDelayed(r, 1000);
while (waitOver == false) {
}
delayedMethod();
waitOver = false;
我的下一次尝试可能是尝试以某种方式使用 Thread 类,以便我可以调用 thread.join()。
我担心,如果失败了,接下来的事情将变得非常漫长和复杂。
有什么建议么?
有解决方案的简单示例吗?
Thanks
编辑:我可能对 Handler/Runnable 是否会导致文字线程感到困惑。
编辑:这是一个游戏。用户进行移动,屏幕更新以显示移动,计算告诉他们得分,重新为屏幕上的框着色,添加延迟以允许用户看到他们的点,然后调用方法来删除彩色方块,当该方法完成时,我们返回到调用它的方法(包含处理程序/可运行),代码继续向下调用另一个方法,导致棋盘的随机方块变成紫色。因此,应该发生用户移动、重新绘制以显示得分、延迟以便用户可以看到得分、重新绘制以擦除方块,然后发生随机紫色方块。有时会发生的情况(据我所知)是随机的紫色方块会在它应该执行之前执行,选择得分的方块之一,进行干扰,并使其清理方法变得混乱并且无法清理。
主要方法(){
...
如果(得分){
方块辉光();
...
//延迟,以便用户可以在清理发生之前看到发光
处理程序可运行
清理();
后延迟
}
...
紫色方块();
}
我希望这不会更加令人困惑。 PurpleSquare 在清理之前运行,事情就搞砸了。
编辑:
尝试过这个:
6
CountDownLatch doneSignal = new CountDownLatch(1);
Handler handler=new Handler();
final LatchedRunnable lr = new LatchedRunnable(doneSignal);
handler.postDelayed(lr, COMPUTER_MOVE_DELAY);
try {
doneSignal.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
class LatchedRunnable implements Runnable {
private final CountDownLatch doneSignal;
LatchedRunnable(CountDownLatch doneSignal) {
this.doneSignal = doneSignal;
}
public void run() {
delayedProcess();
doneSignal.countDown();
}
}
7
ExecutorService executorService = Executors.newFixedThreadPool(5);
final CountDownLatch latch = new CountDownLatch(1);
executorService.execute(new Runnable() {
public void run() {
try {
Looper.prepare();
Handler handler=new Handler();
final Runnable r = new Runnable()
{
public void run()
{
delayedMethodCleanupCalc();
}
};
handler.postDelayed(r, 4000);
} finally {
latch.countDown();
}
}
});
try {
latch.await();
delayedMethodPaintScreen();
} catch (InterruptedException e) {
// todo >> handle exception
}