2

I started a runnnable but did not assign it to a variable. How do I stop it? I know it is a combination of the removeCallbacksAndMessages() method, but I do not know what parameter to pass in to this method since I created an anonymous runnable:

mStartButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            h = new Handler();
            final int delay = 1000; //milliseconds

            h.postDelayed(new Runnable() {
                public void run() {
                    mUpdateRef.addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            int mNumberOfPollsForCurrentDay = (int) dataSnapshot.getChildrenCount();
                            Random r = new Random();
                            int randomPollInRangeOfCurrentDayNumberOfPolls = r.nextInt((mNumberOfPollsForCurrentDay + 1) - 1) + 1;
                            int numberOfPollAnswersAtRandomNumber = (int) dataSnapshot.child(String.valueOf(randomPollInRangeOfCurrentDayNumberOfPolls)).child(POLL_ANSWERS_LABEL).getChildrenCount();
                            Random rr = new Random();
                            int randomAnswerBasedFromRandomPollAnswerChoices = rr.nextInt((numberOfPollAnswersAtRandomNumber + 1) - 1) + 1;
                            mUpdateRef.child(String.valueOf(randomPollInRangeOfCurrentDayNumberOfPolls)).child(POLL_ANSWERS_LABEL).child(String.valueOf(randomAnswerBasedFromRandomPollAnswerChoices)).child("Vote_Count").runTransaction(new Transaction.Handler() {
                                @Override
                                public Transaction.Result doTransaction(MutableData mutableData) {
                                    mutableData.setValue((Long) mutableData.getValue() + 1);
                                    return Transaction.success(mutableData);
                                }

                                @Override
                                public void onComplete(FirebaseError firebaseError, boolean b, DataSnapshot dataSnapshot) {

                                }
                            });

                        }

                        @Override
                        public void onCancelled(FirebaseError firebaseError) {

                        }
                    });
                    h.postDelayed(this, delay);
                }
            }, delay);

        }
    });
tccpg288
  • 3,242
  • 5
  • 35
  • 80
  • I think you need to stop Handler, http://stackoverflow.com/questions/18671067/how-to-stop-handler-runnable – stjepano Feb 19 '16 at 22:01
  • @stjepano - Nope, this Runnable is an anonymous class – OneCricketeer Feb 19 '16 at 22:01
  • One way to stop the runnable is to put a "active" boolean value at the very start of `run()` and toggle that in order to kill the runnable. – OneCricketeer Feb 19 '16 at 22:02
  • @cricket_007, what I meant is to stop Runnable in the context of threading, Runnable by itself is not a thread, only code that is executed by a thread. – stjepano Feb 19 '16 at 22:09
  • @stjepano - I know what you are going for, but if you compare the link you posted with this code, that other question has saved a reference to the Runnable. This question does not - it is an anonymous Runnable that you cannot call removeCallbacks with. – OneCricketeer Feb 19 '16 at 22:11

1 Answers1

5

Calling h.removeCallbacksAndMessages(null) will remove all callbacks and messages as stated in the documentation:

Remove any pending posts of callbacks and sent messages whose obj is token. If token is null, all callbacks and messages will be removed.

Note that this does not stop the runnable if it is already in the middle of executing but will remove it if it is still pending.

George Mulligan
  • 11,813
  • 6
  • 37
  • 50
  • Not sure what you mean by it it is in the middle of executing. Do you mean it will finish its last task before terminating? Your solution works, I appreciate the help, just trying to understand the process a bit more. – tccpg288 Feb 19 '16 at 22:02
  • I wasn't 100% sure I what you meant by "stop a runnable". You are posting the runnable with a delay so if you mean stop a runnable as in stop it from executing before the delay expires then `h.removeCallbacksAndMessages(null)` is what you want. If however you mean stop a runnable as in the delay has already expired and I am currently executing the `run()` method of the runnable then calling `h.removeCallbacksAndMessages(null)` will not stop execution in the middle of the run method. – George Mulligan Feb 19 '16 at 22:06
  • Not sure if that last comment helped or confused you more. Basically `h.removeCallbacksAndMessages(null)` will cancel execution of the Runnable as long as it is still pending (has not started to run yet). If it has started to run then the `Runnable` will still run to completion. – George Mulligan Feb 19 '16 at 22:16
  • What would be the best way to rephrase the question? I am going to edit accordingly. – tccpg288 Feb 19 '16 at 22:18
  • Hmmm that's a good question. I think the only confusing word in the title for me is "stop" and it might make more sense to replace it with "remove". Maybe something like "How to remove a Runnable that is not assigned to a variable from a Handler". – George Mulligan Feb 19 '16 at 22:24
  • Done! Much appreciated – tccpg288 Feb 19 '16 at 22:32