Search code examples
javaandroidandroid-activityhandlerrunnable

How do I stop a runnable when I start another activity?


I have a Android app that shows a dialog when a value is '1' and shows the dialog repeatedly till the value is set to '0'. A Runnable calls a Handler which starts the dialog, and the Runnable loops with a delay.

Problem is that when I go to another activity with the same function and go back, the dialog is already open. This causes my app to crash. I already try to use removeMessage and removeCallback but still have the problem.

Handler

Handler myHandler = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    {
        /* Dialog */
        final AlertDialog.Builder AlertAlarm_Build;
        LayoutInflater inflater = (LayoutInflater) Settings_Activity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        AlertAlarm_Build = new AlertDialog.Builder(Settings_Activity.this);
        final View Disengaged_View;
        Disengaged_View = inflater.inflate(R.layout.disengage_dialog,null);
        final AlertDialog PasswordDialog = AlertAlarm_Build.create();
        PasswordDialog.show();

        final String[] given_password = new String[1];
        final boolean[] Password_Pass = {false};

        //respose
        final RequestQueue requestHander;
        requestHander = (RequestQueue) Volley.newRequestQueue(getApplicationContext());

...//Ask for password

        //New
        PasswordDialog.setOnDismissListener(new DialogInterface.OnDismissListener()
        {
            @Override
            public void onDismiss(DialogInterface dialogInterface)
            {
                recreate();
            }
        });

    }

};

Runnable

    //Runnable
final Runnable aMyRunnable = new Runnable()
{
    @Override
    public void run()
    {
        RequestQueue requestRun;
        requestRun = (RequestQueue) Volley.newRequestQueue(getApplicationContext());

        if(New_engaged[0].equals("1") && New_alarm[0].equals("1"))
        {
            set_engaged[0] = "1";
            myHandler.sendEmptyMessage(0);
        }
        else
        {
            requestRun.add(JOR_SystemCheck);
            myHandler.postDelayed(this,5000);

        }
    }
};

onStop

    protected void onStop() {
        super.onStop();
        myHandler.removeCallbacksAndMessages(aMyRunnable);
        myHandler.removeMessages(0);
    }

Error

/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.djwiz.eclipse5, PID: 17705
              android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@f8866f3 is not valid; is your activity running?
                  at android.view.ViewRootImpl.setView(ViewRootImpl.java:765)
                  at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
                  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:92)
                  at android.app.Dialog.show(Dialog.java:330)
                  at com.example.djwiz.eclipse5.Settings_Activity$1.handleMessage(Settings_Activity.java:68)
                  at android.os.Handler.dispatchMessage(Handler.java:105)
                  at android.os.Looper.loop(Looper.java:164)
                  at android.app.ActivityThread.main(ActivityThread.java:6541)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Solution

  • Based on the documentation for removeCallbacksAndMessages

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

    Your code won't match any token: myHandler.removeCallbacksAndMessages(aMyRunnable);

    So the solution would be to use:

    myHandler.removeCallbacksAndMessages(null);