问题描述
我在 Android 中使用 Runnable 作为循环.像这样:
I'm using Runnable as a loop in Android. As this:
Timer timer = new Timer();
timer.schedule(new looper(m_mainView, this),0, Rate);
每速率"毫秒运行一次.
Which runs every 'Rate' milliseconds.
looper 是这样的:
The looper is as this:
class looper extends TimerTask
{
private ImageView img;
Context c;
public looper(ImageView imgView, Context context)
{
this.img = imgView;
this.c = context;
}
public void run()
{
runOnUiThread(new Runnable() {
@Override
public void run() {
....
我想锁定 run()
中的代码直到它完成,这样如果它在完成之前被调用 - 调用的线程将返回并完成.
I would like to lock the code inside run()
until it is finished, so that if it is called before finished - the thread that calls will return and finish.
我在 run()
中尝试了 synchronized(Object)
方法,但没有用.也试过一个互斥锁,也没用.
I've tried a synchronized(Object)
approach inside run()
which didn't work. Also tried a Mutex, which also didn't work.
帮助:)
推荐答案
looper
对象由 timer.schedule
单独拥有,因此没有人可以调用该对象的run
方法,除了 timer.schedule
.如果 run
方法花费的时间比你指定的时间长,那么 run 方法很可能会在它完成之前再次被调用 - 特别是因为你已经将任务的实际运行传递给了界面线程.
The looper
object is solely owned by the timer.schedule
so no-one can call that object's run
method except the timer.schedule
. If the run
method takes longer that the period you have specified then it is likely that the run method will be called again before it completes - especially since you have passed off the actual running of the the task to the UI thread.
您有两个简单的选择:
- 在您的
run
方法中设置一个标志,表明您正在运行,如果设置了,则使run
什么都不做. - 仅在固定延迟后触发计时器,而不是重复时间.运行结束时,再次将其关闭.
- Set a flag in your
run
method indicating that you are running and makerun
do nothing if it is set. - Fire off the timer after a fixed delay only, not with a repeat time. At the end of your run, fire it off again.
对于 1:
class Looper extends TimerTask {
// ** Add this **
volatile boolean running = false;
public Looper() {
}
@Override
public void run() {
// ** Add this **
if (!running) {
running = true;
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
// ** Add this **
} finally {
running = false;
}
}
}
}
第二种方法:
timer.schedule(new looper(m_mainView, this, Rate),new Date());
...
class Looper extends TimerTask {
final long rate;
final Looper looper;
public Looper(long rate) {
this.rate = rate;
looper = this;
// ...
}
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
// ...
new Timer().schedule(looper, new Date(new Date().getTime() + rate));
}
});
}
}
这篇关于锁定 Runnable 直到完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!