Android: таймер обратного отсчета .cancel() не работает

Я разрабатываю игру, и у меня проблема с обратным отсчетом, который не останавливается. Таймер запускается нормально, как и должен, и должен останавливаться в методе end(). Это хорошо работает, когда ENEMY_HULL проверяется как 0 или меньше, что вычисляется отдельно, когда пользователи нажимают кнопку, и вызывается checkEnemyDefeat(), но не работает, когда ENEMY_CREW равно 0. В обоих случаях сообщение в журнале cat о том, что появляется таймер остановлен, поэтому я предполагаю, что вызывается .cancel(). Я включил весь код, который кажется уместным.

ПРИМЕЧАНИЕ. Все переменные, включая CountDownTimer, являются глобальными переменными.

Вот метод, содержащий таймер:

private void BadGameLoop() { 
    if (GAME_PAUSED == true && !GAME_TIME_STARTED) {
        Log.d(" -------- ", "TIMER STARTED");
        GAME_PAUSED = false;
        GAME_TIME_STARTED = true;

        gameTimer = new CountDownTimer(GAME_TIME, UPDATE_RATE) {
            @Override
            public void onTick(long millisUntilFinished) {
                TICKS++;

                timer.setText(String.valueOf(GAME_TIME / 1000 - TICKS / 10));



                if((CREW_BOARDING > 0 || ENEMY_CREW_BOARDING > 0) && TICKS%10 == 0){
                    crewFightCalculator();
                }
                updateViews();
            }
            @Override
            public void onFinish() {

                TICKS=0;
                GAME_TIME_STARTED = false;
                GAME_PAUSED = true;
                end();
            }
        };gameTimer.start();
    }
}

Далее идет метод экипажаFightCalculator:

private void crewFightCalculator(){
    // this just changes the values of ENEMY_CREW (global variable) and then
//calls checkEnemyDefeat() to verify if it should end the timer or not

    checkEnemyDefeat();
}

Методы checkEnemyDefeat и end:

private void checkEnemyDefeat(){
    if(ENEMY_HULL <= 0){  
        updateViews(); 

        end();   
    }else if ( ENEMY_CREW < 1){
        updateViews(); 

        end(); 
    }
}
private void end(){ 
    if(GAME_TIME_STARTED){
        GAME_TIME_STARTED = false;
        gameTimer.cancel();
        Log.d("---------"," TIMER STOPPED !");
    }
    // do more stuff
}

Мне просто странно, почему это не работает. Мое единственное предположение состоит в том, что это как-то связано с тем фактом, что .cancel() не запускается цепочкой функций, запускаемых пользователем.


person Daniel D.    schedule 29.08.2015    source источник
comment
У вас есть gameTimer в качестве глобальной переменной, верно? Попробуйте поставить ниже отмену gameTimer.onFinish();   -  person Skizo-ozᴉʞS    schedule 29.08.2015
comment
В противном случае попробуйте сделать его статическим, например private static CountDownTimer gameTimer;   -  person Skizo-ozᴉʞS    schedule 29.08.2015
comment
Действительно, CountDownTimer — это статическая глобальная переменная. Я попытался поместить gameTimer.onFinish() ниже cancel(), но это просто перезапустило таймер... странно...   -  person Daniel D.    schedule 29.08.2015


Ответы (1)


Единственное решение этой проблемы, которое я нашел, состояло в том, чтобы изменить метод onTick, чтобы он каждый раз проверял, должен ли он запускать или останавливать таймер следующим образом:

private void BadGameLoop() { 
if (GAME_PAUSED == true && !GAME_TIME_STARTED) {
    Log.d(" -------- ", "TIMER STARTED");
    GAME_PAUSED = false;
    GAME_TIME_STARTED = true;

    gameTimer = new CountDownTimer(GAME_TIME, UPDATE_RATE) {
        @Override
        public void onTick(long millisUntilFinished) {
        if(GAME_TIME_STARTED) {
            TICKS++;

            timer.setText(String.valueOf(GAME_TIME / 1000 - TICKS / 10));



            if((CREW_BOARDING > 0 || ENEMY_CREW_BOARDING > 0) && TICKS%10 == 0){
                crewFightCalculator();
            }
            updateViews();

        }else{
            gameTimer.cancel();
        }}
        @Override
        public void onFinish() {

            TICKS=0;
            GAME_TIME_STARTED = false;
            GAME_PAUSED = true;
            end();
        }
    };gameTimer.start();
}
}

Тем не менее, я не могу понять, почему он не работал должным образом раньше.

person Daniel D.    schedule 01.09.2015
comment
Другими словами, метод cancel не работает, и итерации будут продолжаться. Итак, else в коде не нужен, а проблема в самом классе :( - person JCarlosR; 03.08.2017