1

EXCEPTION: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

I have a popupWindow() which I am showing upon a button click. I am using my own method initiatePopUpWindow(Activity) to show the popup (I took the code from an online tutorial). I am trying to save its state on orientation change so I am using a boolean popupWindowOpen to keep a check. But during the orientation change, it is giving me this error. Any help on how can I fix this?

MainActivity.java

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private PopupWindow pw;
    private volatile boolean popupWindowOpen = false;

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

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                initiatePopUpWindow(MainActivity.this);
            }
        });

        if(savedInstanceState != null) {
            popupWindowOpen = savedInstanceState.getBoolean("popupWindowOpen");
        }
    }

    @Override
    public void onResume() {
        super.onResume();

        if(popupWindowOpen) {
            initiatePopUpWindow(MainActivity.this);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putBoolean("popupWindowOpen", popupWindowOpen);
    }

    private void initiatePopUpWindow(final Activity context) {
        popupWindowOpen = true;

        try {
            if(!isFinishing()) {
                DisplayMetrics displayMetrics = new DisplayMetrics();
                getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
                int height = displayMetrics.heightPixels;
                int width = displayMetrics.widthPixels;
                LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                View layout = inflater.inflate(R.layout.email_popup_layout, (ViewGroup) findViewById(R.id.popup_window));
                pw = new PopupWindow(layout, (int)(1.0 * width), (int)(0.75 * height), true);
                pw.setAnimationStyle(R.anim.zoom_in);
                pw.showAtLocation(layout, Gravity.CENTER, 0, 0);

                Button click = (Button) layout.findViewById(R.id.pop_up_button);
                final EditText et = (EditText) layout.findViewById(R.id.pop_up_edittext);
                click.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        String s = et.getText().toString();
                        popupWindowOpen = false;
                        pw.dismiss();

                        Snackbar.make(findViewById(R.id.drawer_layout), s, Snackbar.LENGTH_LONG).show();
                    }
                });
            }
            else {
                Toast.makeText(getBaseContext(), "isFinishing", Toast.LENGTH_LONG).show();
            }
        }
        catch (Exception e) {
            Snackbar.make(findViewById(R.id.drawer_layout), "Could not initiate Pop-up - " + e.toString(), Snackbar.LENGTH_INDEFINITE).show();
        }
    }
}

How do I solve this problem? Please Help. Thank you.

EDIT: The error is at the line pw.showAtLocation(layout, Gravity.CENTER, 0, 0);. Adding logcat output

logcat output

11-15 22:30:24.188 14859-14859/com.onclavesystems.cestemoeducare E/[EGL-ERROR]: void __egl_platform_dequeue_buffer(egl_surface*):1618: failed to dequeue buffer from native window (0x77ded238); err = -19, buf = 0x0,max_allowed_dequeued_buffers 3
11-15 22:30:24.273 14859-14859/com.onclavesystems.cestemoeducare E/Qmage: onDecode : QmageDecodeFrame 20140421 Rev.6376 
11-15 22:30:24.273 14859-14859/com.onclavesystems.cestemoeducare E/Qmage: This is decoding
11-15 22:30:24.273 14859-14859/com.onclavesystems.cestemoeducare E/Qmage: decoding stream->hasLength()
11-15 22:30:24.273 14859-14859/com.onclavesystems.cestemoeducare E/Qmage: onDecode : QmageDecParseHeader call : QM
11-15 22:30:24.283 14859-14859/com.onclavesystems.cestemoeducare E/Qmage: Qmage parsing for decoding ok
11-15 22:30:24.283 14859-14859/com.onclavesystems.cestemoeducare E/Qmage: onDecode :  QmageHeader.NinePatched 0
11-15 22:30:24.283 14859-14859/com.onclavesystems.cestemoeducare E/Qmage: onDecode : QmageHeader Height() 72 Width() : 72 sampleSize : 1
11-15 22:30:24.283 14859-14859/com.onclavesystems.cestemoeducare E/Qmage: normal image decoding
11-15 22:30:24.283 14859-14859/com.onclavesystems.cestemoeducare E/Qmage: onDecode : QmageDecodeFrame call : QM
11-15 22:30:24.318 14859-14859/com.onclavesystems.cestemoeducare E/Qmage: onDecode : return true QM
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime: FATAL EXCEPTION: main
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime: Process: com.onclavesystems.cestemoeducare, PID: 14859
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime: java.lang.RuntimeException: Unable to resume activity {com.onclavesystems.cestemoeducare/com.onclavesystems.cestemoeducare.ADITI}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3069)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3098)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2469)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4073)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.access$1000(ActivityThread.java:172)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1314)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:146)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5653)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:515)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:  Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.view.ViewRootImpl.setView(ViewRootImpl.java:771)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:278)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.widget.PopupWindow.invokePopup(PopupWindow.java:1071)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.widget.PopupWindow.showAtLocation(PopupWindow.java:895)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.widget.PopupWindow.showAtLocation(PopupWindow.java:859)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at com.onclavesystems.cestemoeducare.ADITI.initiatePopUpWindow(MainActivity.java:238)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at com.onclavesystems.cestemoeducare.ADITI.onResume(MainActivity.java:80)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1198)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.Activity.performResume(Activity.java:5618)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3059)
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3098) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2469) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4073) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.access$1000(ActivityThread.java:172) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1314) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:146) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5653) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:515) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) 
11-15 22:30:24.383 14859-14859/com.onclavesystems.cestemoeducare E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)

Line 80 is pw.showAtLocation(layout, Gravity.CENTER, 0, 0); 

Sajib Acharya
  • 1,666
  • 5
  • 29
  • 54
  • at which line getting issue? probably `getBaseContext()` causing issue so try to use `context` – ρяσѕρєя K Nov 15 '15 at 16:33
  • @ρяσѕρєяK, this is the line I am getting the exception at: `LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);` – Sajib Acharya Nov 15 '15 at 16:55
  • @ρяσѕρєяK, sorry, I gave wrong information. The error is shown on another line. Updated question. – Sajib Acharya Nov 15 '15 at 17:05
  • @SajibAcharya: call `pw.dismiss();` in `onStop()` method then check what happening – ρяσѕρєя K Nov 15 '15 at 17:20
  • @ρяσѕρєяK, I tried that. Not working. in `onStop()` I used: `if(pw != null) { pw.dismiss(); }` – Sajib Acharya Nov 15 '15 at 17:27
  • @MrsEd, yes, I saw this SO post before posting my question. I used the `isFinishing()` condition in my code after reading this. But I am not trying to update my UI from a background thread. What I don't get is that the button click calls `initiatePopUpWindow()` and everything is fine. But when the same method is called from `onResume()`, it gives me the error. Why? – Sajib Acharya Nov 15 '15 at 18:10
  • @MrsEd, sure, I'll be waiting. :) – Sajib Acharya Nov 16 '15 at 02:24

1 Answers1

0

I found it easier to solve this by managing the configuration change for the activity rather than saved instance state.

So in the manifest for this activity:

<activity
    android:configChanges="orientation|screenSize"

Then in the activity itself. No need for a boolean, (also no need to use volatile, as there are no threading issues here). By manually managing your configuration changes (screen orientation changes) you are preventing the app from being destroyed each time

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

    fab = (Button) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            initiatePopUpWindow(MainActivity.this);
        }
    });


}


@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
}

private void initiatePopUpWindow(final Activity context) {

    try {

            DisplayMetrics displayMetrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
            int height = displayMetrics.heightPixels;
            int width = displayMetrics.widthPixels;
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View layout = inflater.inflate(R.layout.email_popup_layout, (ViewGroup) null);
            pw = new PopupWindow(layout, (int)(1.0 * width), (int)(0.75 * height), true);

            pw.showAtLocation(layout, Gravity.CENTER, 0, 0);

            Button click = (Button) layout.findViewById(R.id.pop_up_button);
            final EditText et = (EditText) layout.findViewById(R.id.pop_up_edittext);
            click.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    String s = et.getText().toString();
                    pw.dismiss();

                    Toast.makeText(getBaseContext(), "Dismissed", Toast.LENGTH_LONG).show();
                }
            });


    }
    catch (Exception e) {
    Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
    }
}

No need to worry about saved instance state, checking a boolean value or managing your onresume.

  • This is not helping. Giving me the same error. Please check my edited question, I gave a wrong information previously, the exception was thrown on a different line of code. – Sajib Acharya Nov 15 '15 at 17:08
  • I tried this solution. But this crashes the whole application at the start with `NPE` at `savedInstanceState.putBoolean(POP_UP_OPEN, isPopUpOpen);` under the `else` statement in `onCreate(Bundle)`. Also Android Studio gives me warning at this line that it may produce `NPE`. – Sajib Acharya Nov 16 '15 at 06:21