Elliptica
Elliptica

Reputation: 4332

CountDownTimer Is Not Cancelling --- Continues to Run After Cancel()

I've implemented a CountDownTimer in my code as follows: At the top of the class, I create

CountDownTimer myTimer;

Then when a user presses button Start, the following method is called:

private void countme() 
{
    final int tick = 500;
    final int countTime = 10000;

    myTimer = new CountDownTimer(countTime, tick) {

        @Override
        public void onTick(final long millisUntilFinished) { }

        @Override
        public void onFinish() {
            myPicture.setVisibility(View.GONE);
        }
    };

    myTimer.start();
}

I have button Stop all myTimer.cancel(). As you can see, if the timer is not cancelled, myPicture will disappear.

Even if I click the stop button so that myTimer.cancel() is called (I checked this with log statements), the counter still continues to count down and to make the picture disappear when it's done.

Why isn't it stopping? How do I get it to actually cancel?

To clarify, I do know how to implement Runnable timers, but they are not as accurate for my needs as CountDownTimers are, which is why I'm not using them in this case.

Upvotes: 2

Views: 3848

Answers (4)

garry
garry

Reputation: 429

After a lot of tries, trick is to declare the timer in onCreate but start and cancel it in some other method. The onFinish() will not call after cancelling the timer.

    myTimer = new CountDownTimer(COUNT_DOWN_TIME, TICK) {
        @Override
        public void onTick(final long millisUntilFinished) {

            ((TextView) findViewById(R.id.textView3)).setText(""
                    + millisUntilFinished);
        }

        @Override
        public void onFinish() {
            findViewById(R.id.timer_imageBiew).setVisibility(View.GONE);
        }
    };



    private fun startTimer() {
           myTimer .start()
   }

   private fun stopTimer() {
           myTimer .cancel()
   }

Upvotes: 2

Hitesh Sahu
Hitesh Sahu

Reputation: 45170

This is working example , I have implemented both handler and timer you can pick one .

import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainActivity extends Activity {

    private CountDownTimer myTimer;
    final int TICK = 500;
    final int COUNT_DOWN_TIME = 2000;

    // Option 2 using handler
    private Handler myhandler = new Handler();
    private Runnable runnable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Option 1 using timer
        myTimer = new CountDownTimer(COUNT_DOWN_TIME, TICK) {
            @Override
            public void onTick(final long millisUntilFinished) {

                ((TextView) findViewById(R.id.textView3)).setText(""
                        + millisUntilFinished);
            }

            @Override
            public void onFinish() {
                findViewById(R.id.timer_imageBiew).setVisibility(View.GONE);
            }
        };

        // Option 2 using handler
        runnable = new Runnable() {
            @Override
            public void run() {

                findViewById(R.id.handlerImageView).setVisibility(View.GONE);

            }
        };

        findViewById(R.id.start_timer).setOnClickListener(
                new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // Option 1 using timer
                        myTimer.start();

                        // Option 2 using handler
                        myhandler.postDelayed(runnable, COUNT_DOWN_TIME);

                    }
                });

        findViewById(R.id.stop_timer).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                // Option 1 stop timer
                myTimer.cancel();

                // Option 2 stop handler
                myhandler.removeCallbacks(runnable);
            }
        });
    }

}

Upvotes: 0

AL.
AL.

Reputation: 37818

Your post is very odd. I just tried doing a sample activity:

public class MainActivity extends AppCompatActivity {

    CountDownTimer myTimer;
    Button btnStart;
    Button btnCancel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sample2);

        btnStart = (Button) findViewById(R.id.start);
        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                countme();
                Toast.makeText(MainActivity.this, "Count Started!", Toast.LENGTH_SHORT).show();
            }
        });

        btnCancel = (Button) findViewById(R.id.cancel_timer);
        btnCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myTimer.cancel();
                Toast.makeText(MainActivity.this, "Clicked Stop Timer!", Toast.LENGTH_SHORT).show();
            }
        });

    }

    private void countme() {
        final int tick = 500;
        final int countTime = 10000;

        myTimer = new CountDownTimer(countTime, tick) {

            @Override
            public void onTick(final long millisUntilFinished) {
                Log.d(MainActivity.class.getSimpleName(), "onTick()");
            }

            @Override
            public void onFinish() {
                // myPicture.setVisibility(View.GONE);
                Toast.makeText(MainActivity.this, "In onFinish()", Toast.LENGTH_SHORT).show();
            }
        };

        myTimer.start();
    }

}

It works perfectly fine. It stops the timer. But I went and looked around and found this answer where it mentions that CountDownTimer doesn't seem to work, so he suggested to use a Timer instead. Do check it out. Cheers!

Upvotes: 1

Vishwesh Jainkuniya
Vishwesh Jainkuniya

Reputation: 2839

Here in your method countme() you are initializing myTimer, so outside this method myTimer has no value.

Use this

Declare at the top

CountDownTimer myTimer;
final int tick = 500;
final int countTime = 10000;

In the onCreate method of Activity or Fragment

 myTimer = new CountDownTimer(countTime, tick) {

        @Override
        public void onTick(final long millisUntilFinished) { }

        @Override
        public void onFinish() {
            myPicture.setVisibility(View.GONE);
        }
    };

Now use myTimer.start() to start and myTimer.cancel() to stop it.

Hope you understood.

Upvotes: 1

Related Questions