Android onPause приложение заморозить поток

Я хочу сделать секундомер. И я создаю класс секундомера, как это. И когда я вызываю onPause в другой Activity, его приложение заморозить.

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();

1 ответ

Решение

Ты не можешь Object.wait() в run метод вызывается из Handler, который, вероятно, работает в основном потоке /UI.

Все приложение для Android координируется с помощью коротких методов, которые регистрируются в основной ветке / пользовательском интерфейсе. Вы, наверное, тоже регистрируете там свой секундомер. Невозможно выполнить 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.

Другие вопросы по тегам