当活动暂停时调用cancel(),CountDownTimer的onFinish()未被调用

4
我有一个通过MediaPlayer播放音乐的活动。通常情况下,当我想停止歌曲时,我会将MediaPlayer传递给一个CountDownTimer,将音量淡出至零,然后释放MediaPlayer。这似乎很好用,但是当我的活动暂停时(例如触摸主页按钮),我遇到了一个问题。
我在onPause中调用cancel(),但由于活动正在暂停,CountDownTimer在被销毁之前似乎从未收到消息(?),因此CountDownTimer的finish()没有被调用。
这导致应用程序退出后,音乐仍然以CountDownTimer上次设置的音量播放,但从未结束。所以现在我被困在我的应用程序外面,MediaPlayer在运行,而且没有办法停止它(非常糟糕)。
即使我调用了cancel,当活动退出时,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.

如何在退出活动时成功中止所有倒计时器?
1个回答

19

看一下源代码。你会发现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();

啊,谢谢你提醒我这个问题。我在其他地方读到cancel确实会显式调用onFinish,但是我想那是错的。应该先检查一下。感谢! - Tim
没有问题。我个人对这门课程有一些不满,我和另一个用户在他的问题中讨论过。 - Sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接