【问题标题】:ScheduledThreadPoolExecutor only "ticking" onceScheduledThreadPoolExecutor 只“滴答”一次
【发布时间】:2015-04-08 18:11:29
【问题描述】:

我使用CountDownTimer 来实现我在Activity 中的一些倒计时功能。我决定离开CountDownTimer 并使用ScheduledThreadPoolExecutor,因为CountDownTimers 不能在onTick() 中取消自己。

由于某种原因,我在以下代码中的Runnable 只执行一次。我不确定为什么它没有执行多次。 destroyCountdownTimer() 函数未命中。

private ScheduledThreadPoolExecutor mCountdownTimer;
private Tick mTick;

class Tick implements Runnable {
    @Override
    public void run() {
        Log.e("tick", String.valueOf(mAccumulatedMilliseconds));
        mAccumulatedMilliseconds += 1000;
        populateTimeAccumulated();
        populateTimeRemaining();
        updatePercentages();

        if (mTotalMilliseconds <= mAccumulatedMilliseconds) {
            destroyCountdownTimer();
        }
    }
}

private void startCountdown() {
    if (mAccumulatedMilliseconds < mTotalMilliseconds) {
        mCounterIsRunning = true;

        if (mCountdownTimer == null) {
            mCountdownTimer = new ScheduledThreadPoolExecutor(1);
        }

        if (mTick == null) {
            mTick = new Tick();
        }

        mCountdownTimer.scheduleAtFixedRate(mTick, 1000, 1000, TimeUnit.MILLISECONDS);
    }
}

private void destroyCountdownTimer() {
    if (mCountdownTimer != null) {
        mCountdownTimer.shutdownNow();
        mCountdownTimer = null;
    }

    if (mTick != null) {
        mTick = null;
    }
}

【问题讨论】:

  • 将日志记录添加到您的取消逻辑(或者如果必须,使用断点调试器)并查看是否触发。
  • 我在调用中设置了一个断点来销毁计时器。它没有被击中。在注释掉 Runnable 中的填充/更新调用后,一切正常。我看不出为什么他们中的任何人都应该持有Runnable。当我使用CountDownTimer 时,它们都运行良好。我稍后会用其中的代码更新主帖。

标签: android runnable


【解决方案1】:

documentation 说:

If any execution of the task encounters an exception, subsequent executions are suppressed.

将 try-catch 块添加到您的 Tick runnable。

【讨论】:

  • populateTimeAccumulated()内部有异常。
  • 04-08 13:24:03.609: E/Tick(2722): error: android.view.ViewRootImpl$CalledFromWrongThreadException: 只有创建视图层次结构的原始线程才能触摸它的视图。跨度>
  • 我是否需要将指向Activity 的指针传递给Runnable 或其他东西?
  • 需要在 UI 线程中查看所有操作。为此,您可以使用 Activity 的 runOnUiThread 方法 - 在其可运行对象中执行所有操作。
猜你喜欢
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多