Search code examples
androidtooltipandroid-support-library

TooltipCompat causing BadTokenException


I created a PopupWindow that displays a list of buttons. Originally, for each item in my list, I implemented an OnLongClickListener to display a Toast message in the view holder:

private inner class MenuItemViewHolder (itemView: View) {

    val button: ImageButton = itemView.findViewById(R.id.button);

    fun bindItem(item: MenuItem) {
        button.setImageDrawable(item.icon)
        button.isEnabled = item.isEnabled

        button.setOnClickListener { popupWindow.onItemClick(item) }
        button.setOnLongClickListener {
            Toast.makeText(context, item.title, Toast.LENGTH_SHORT).show()
        }
    }

}

I wanted to update this to display a tooltip message instead:

TooltipCompat.setTooltipText(button, item.title)

But when I long click the button, I get the following error:

10-06 16:32:35.470 22492-22492/com.example.app.ui E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.app.ui, PID: 22492
        android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@e214c8e 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 com.android.internal.view.TooltipPopup.show(TooltipPopup.java:74)
            at android.view.View.showTooltip(View.java:26365)
            at android.view.View.showLongClickTooltip(View.java:26389)
            at android.view.View.performLongClickInternal(View.java:6344)
            at android.view.View.performLongClick(View.java:6294)
            at android.view.View.performLongClick(View.java:6312)
            at android.view.View$CheckForLongPress.run(View.java:24662)
            at android.os.Handler.handleCallback(Handler.java:789)
            at android.os.Handler.dispatchMessage(Handler.java:98)
            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)

I found some answers to similar questions, which all seem to suggest that the Activity the View belongs to is not in the correct state when they try to add a new Window. But the Activity is definitely running before I perform a long press on the button, and no destructive lifecycle methods have been called (i.e. onPause, onStop, onDestroy).

What could be causing this error? Could it have something to do with the fact that the ListView is being displayed in a PopupWindow? If so, how can I remedy the situation?


I added the necessary code to a GitHub project. If you run the application, you will notice that the tooltip works fine on the menu button (overflow button). But when you open the menu and long press on any of the icons, the application crashes with the above error.


Solution

  • Have you seen this bug report? This looks like your issue but it is unclear if the changes have been released or not. My guess for your issue is that the tooltip popup is being attached to the wrong window.