ScheduledThreadPoolExecutor only "ticking" once
Asked Answered
C

1

3

I was using a CountDownTimer for some countdown functionality I have in my Activity. I decided to move away from CountDownTimer and use ScheduledThreadPoolExecutor because CountDownTimers can't cancel themselves in onTick().

For some reason, my Runnable in the following code only executes once. I'm not sure why it isn't executing multiple times. The destroyCountdownTimer() function is not getting hit.

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;
    }
}
Counterweight answered 8/4, 2015 at 18:11 Comment(2)
Add logging to your cancellation logic (or if you must, use the breakpoint debugger) and see if that is triggering.Tiloine
I've set a breakpoint in the call to destroy the timer. It is not being hit. After commenting out the populate/update calls inside the Runnable, everything is working fine. I see no reason why any of them should be holding up the Runnable. They were all functioning perfectly fine when I was using a CountDownTimer. I will update the main post with the code inside of them in a moment.Counterweight
I
5

The documentation says:

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

Add try-catch block to your Tick runnable.

Interpretative answered 8/4, 2015 at 18:21 Comment(4)
There is an exception inside populateTimeAccumulated().Counterweight
04-08 13:24:03.609: E/Tick(2722): error: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.Counterweight
Do I need to pass a pointer to the Activity to the Runnable or something?Counterweight
Need to make all actions with view in UI thread. For that you can use runOnUiThread method of Activity - do everything inside its runnable.Interpretative

© 2022 - 2024 — McMap. All rights reserved.