我正在尝试在一个Thread中运行一个CountDownTimer,但它只是没有工作..
所以在MainActivitys onCreate中我按下按钮点击它:
public void onClick(final View v) {
Log.d("Main", "onClick");
runOnUiThread(runner);
}
runner
是实现Runnable
的类的实例:
private CountDownLatch doneSignal = new CountDownLatch(1);
@Override
public void run() {
Log.d("WR", "run");
this.countDown(20);
Log.d("WR", "waiting");
try {
doneSignal.await();
} catch (final InterruptedException ex) {
Log.e("WR", ex.getMessage(), ex);
}
Log.d("WR", "waited");
}
private void countDown(int time) {
final CountDownTimer timer = new CountDownTimer(time * 1000, 1000) {
@Override
public void onTick(final long millisUntilFinished) {
Log.d("WR", "onTick");
}
@Override
public void onFinish() {
Log.d("WR", "onFinish");
doneSignal.countDown();
}
};
Log.d("WR", "starting");
timer.start();
Log.d("WR", "started");
}
使用此代码,应用程序在登录onClick,运行和启动后冻结。
将runOnUiThread(runner)
更改为new Thread(runner).start();
会导致应用程序在登录onClick后立即崩溃而不再输出。
一些研究表明,由于使用了Handler,CountDownTimer需要在UI-Thread上运行。但它只是冻结了。
当我删除整个Thread内容并只在Buttons onClick中调用runner.run();
(同时删除运行器实例中的实现Runnable)时,我得到以下日志条目:onCLick, run, starting, started, waiting
。但是没有任何反应,好像计时器没有运行,没有调用onTick方法。
如何修复我的CountDownTimer?
答案 0 :(得分:2)
CountDownTimer
在Ui Thread上运行,它必须在UI线程上运行,因为在内部它使用一个Handler,而后者又需要一个Looper。 runOnUiThread(runner);
无论跑者做什么,都在UI线程上运行。
private CountDownLatch doneSignal = new CountDownLatch(1);
在UI线程上调用await()
会阻止它,并且由于countDown()
在同一个线程上运行,您实际上dead-locked
您的应用