我想制作秒表。我创建这样的秒表类。当我在另一个Activity中调用onPause时它的冻结应用程序。
public class StopWatch implements Runnable {
private Object mPauseLock;
private boolean mPaused;
private boolean mFinished;
private ArrayList<TextView> textFields;
private Handler mHandler = new Handler();
public StopWatch( ArrayList<TextView> textFields) {
mPauseLock = new Object();
mPaused = false;
mFinished = false;
this.textFields =textFields;
}
public void run() {
textFields.get(1).setText("progressing...");
if (!mPaused) {
mHandler.postDelayed(this, 1000);
}
synchronized (mPauseLock) {
while (mPaused) {
try {
mPauseLock.wait();
} catch (InterruptedException e) {
}
}
}
}
public void onPause() {
synchronized (mPauseLock) {
mPaused = true;
}
}
public void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
}
}
我在另一个View中创建了类的实例。有人能解开我的问题吗?
stopky = new StopWatch(textFields);
stopky.run();
// do another stuff and register buttons with onClickListener and call
stopky.onPause(); // freeze application
stopky.onResume();
答案 0 :(得分:1)
在Object.wait()
调用的run
方法中,你不能Handler
,它可能在主/ UI线程上运行。
整个Android应用程序通过在main / UI Thread中注册的简短方法进行协调。你也可能在那里注册你的秒表。在那里执行while
循环并且同时处理来自用户界面的事件是不可能的。
快速解决方案是重新安排run
方法并在下次调用时检查状态。基本上是这样的:
public void run() {
textFields.get(1).setText("progressing...");
if (!mPaused) {
// do what has to be done when stopwatch is running
mHandler.postDelayed(this, 1000);
} else {
// just re-schedule with a shorter delay
mHandler.postDelayed(this, 10);
}
}
更好的方法是采用完全事件驱动的设计,避免在秒表停止时调用秒表。在这种情况下,您只需从Button的事件处理程序重新启动它。