Search code examples
javaandroidandroid-activityback-buttonandroid-handler

How to stop/cancel a runnable when pressing on android phone's back button?


In my project, I have an activity called "ExamMenuActivity" where I can choose between "Addition, Subtraction, Multiplication and Division" activities.

In Addition activity (called ExamAdditionActivity) I have a handler method to regenerate the question form after a given answer. Everything seems working fine, I can generate the question and give an answer and after giving an answer, a new question is generated in 2 seconds.

The issue I am having is, after I give a correct or a wrong answer to the question, within 2 seconds, if I quickly press on the back button of the phone and don't wait for the question to regenerate, I come back to the Exam Menu page as I wanted (back to ExamMenuActivity) but the screen changes back to ExamAdditionActivity and I see a new generated question again.

So I want to be able to come back to Exam Menu activity again when I press on the back button of the phone before the question regenerates and I don't want to face back the ExamAdditionActivity again with a new generated question (say I changed my mind after giving an answer to an addition question and I wanted to choose another activity from the menu and I didn't wait for at least 2 seconds). I have tried overriding the activity with onBackPressed method:

@Override
public void onBackPressed() {
    super.onBackPressed();
    finish();
}

but unfortunately that didn't work.

Here is how I regenerate the question. I basically restart the same activity in two seconds with a handler ( there was a runnable within my handler code but since it was showing anonymous, android studio offered me to change it to a lambda function) :

private void regenerateQuestion() {
        new Handler().postDelayed(() -> {
            Intent restartExamAdditionActivity = new Intent(ExamAdditionActivity.this, ExamAdditionActivity.class);

            overridePendingTransition(0, 0);
            startActivity(restartExamAdditionActivity);
            finish();
            overridePendingTransition(0, 0);
        }, TIME_OUT);

    }

Even though I am not sure but I think I am having the problem in button listeners area since I give an answer to the question and call regenetate() method there under each button.

I hope there can be an answer to my issue. Thank you so much for stopping by to check on my post!


Solution

  • Create your Handler as a member variable of your class, like this:

    Handler myHandler = new Handler();
    

    Create your Runnable as a member variable of your class, like this:

    Runnable myRunnable = new Runnable() {
        @Override
        public void run() {
            Intent restartExamAdditionActivity = new Intent(ExamAdditionActivity.this, ExamAdditionActivity.class);
    
            overridePendingTransition(0, 0);
            startActivity(restartExamAdditionActivity);
            finish();
            overridePendingTransition(0, 0);
        }
    };
    

    Post the Runnable using the new variable:

    myHandler.postDelayed(myRunnable, TIME_OUT);
    

    When you want to cancel the regeneration, do this:

    myHandler.removeCallbacks(myRunnable);