1

我想做秒表。我创建了这样的秒表类。当我在另一个 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();
    }
}

}

我在另一个视图中创建类的实例。有人可以解释我哪里有问题吗?

stopky = new StopWatch(textFields);
stopky.run();

// do another stuff and register buttons with onClickListener and call
stopky.onPause(); // freeze application
stopky.onResume();
4

1 回答 1

1

您不能使用从 a 调用的方法Object.wait(),该方法可能在 main/UI 线程上运行。runHandler

整个 Android 应用程序通过向主/UI 线程注册的短方法进行协调。你可能也在那里注册你的秒表。不可能在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 的事件处理程序重新启动它。

于 2013-04-11T06:31:38.987 回答