CountDownTimer onFinish() не вызывается, если я вызываю cancel(), когда активность приостанавливается

У меня есть активность, которая воспроизводит музыку через файл MediaPlayer. Обычно, когда я хочу остановить песню, я передаю MediaPlayer CountDownTimer, который уменьшает громкость до нуля, а затем отпускает MediaPlayer. Кажется, это работает нормально, за исключением того, что у меня проблема, когда моя деятельность приостанавливается, например, после нажатия кнопки «Домой».

Я вызываю cancel() для CountDownTimer в onPause, но кажется, что, поскольку активность приостанавливается, CountDownTimer никогда не получает сообщение до того, как оно будет уничтожено (?), и поэтому finish() CountDownTimer не вызывается.

Результатом этого является то, что после выхода из приложения музыка продолжает воспроизводиться с той громкостью, которая была последней установлена ​​в CountDownTimer, но никогда не заканчивается. Итак, теперь я застрял в своем приложении с запущенным MediaPlayer и не могу его остановить (очень плохо).

Нормально ли, что CountDownTimer не вызывается onFinish при завершении действия, даже если я вызвал отмену?

Это мой код:

public void StopSong(boolean fadeout){
    musicPlaying = false;
    if(_player != null) {
        final int fadeTime = 1000;
        CountDownTimer timer = new CountDownTimer(fadeTime,50) {
            final private MyMusicPlayer mFadePlayer = _player;

            @Override
            public void onTick(long millisUntilFinished) {
                mFadePlayer.setFade((float)millisUntilFinished / (float)fadeTime);
                Log.d("tag", "Fade timer " + millisUntilFinished+ "ms remaining.");
            }

            @Override
            public void onFinish() {
                mFadePlayer.stop();
                mFadePlayer.release();
                Log.d("tag", "Fade timer finished, releasing resource.");
            }
        };
        timer.start();
        mFadeTimers.add(timer);
        Log.d("tag", "Song stopping, starting fade timer.");
        _player = null;
    }
}

И в onPause:

    for(CountDownTimer t : mFadeTimers){
        Log.d("tag", "Cancelling fade timer on destroy.");
        t.cancel();
    }
    mFadeTimers.clear();

Если бы все работало нормально, я бы увидел сообщение журнала «Отмена таймера затухания», за которым следует «Таймер затухания завершен, выпуск», но я никогда не получаю сообщение onFinish() logcat.

Я просто вижу это:

 tag     Song stopping, starting fade timer.
 tag     Application exiting, destroying all audio resources
 tag     Cancelling fade timer on destroy.

Как я могу успешно прервать все мои таймеры обратного отсчета при выходе из активности?


person Tim    schedule 20.10.2012    source источник


Ответы (1)


Взгляните на исходный код. Вы увидите, что cancel() не вызывает onFinish(), просто так устроен CountDownTimer.

Вы можете сами позвонить onFinish():

for(CountDownTimer t : mFadeTimers){
    Log.d("tag", "Cancelling fade timer on destroy."); // ought to read "in onPause", right?
    t.cancel();
    t.onFinish();
}
mFadeTimers.clear();
person Sam    schedule 20.10.2012
comment
А, спасибо, что предупредил меня об этом. Я где-то читал, что отмена явно вызывает onFinish, но я думаю, что это было просто неправильно. Надо было сначала проверить. Спасибо! - person Tim; 21.10.2012
comment
Нет проблемы. Лично у меня есть несколько претензий к этому классу, которые мы с другим пользователем обсуждали в его вопросе. - person Sam; 21.10.2012