skydoves / Balloon

:balloon: Modernized and sophisticated tooltips, fully customizable with an arrow and animations for Android.
https://skydoves.github.io/libraries/balloon/html/balloon/com.skydoves.balloon/index.html
Apache License 2.0
3.75k stars 291 forks source link

android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@8722970 is not valid; is your activity running? #366

Closed Arm63 closed 1 year ago

Arm63 commented 2 years ago

Please complete the following information:

Describe the Bug:

Open PopupWindow (My) Make it child view anchor for Balloon And show balloon

Expected Behavior:

"Balloon pop up" must be shown, but application crashed

android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@82e619c is not valid; is your activity running? at android.view.ViewRootImpl.setView(ViewRootImpl.java:1593) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:509) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:133) at android.widget.PopupWindow.invokePopup(PopupWindow.java:1688) at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1408) at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1374) at com.skydoves.balloon.Balloon.showOverlayWindow(Balloon.kt:812) at com.skydoves.balloon.Balloon.access$showOverlayWindow(Balloon.kt:143) at com.skydoves.balloon.Balloon$showAlign$$inlined$show$1.run(Balloon.kt:777) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at android.app.ActivityThread.main(ActivityThread.java:8663) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

Arm63 commented 2 years ago

P.S and it's all because of this setter "balloon.setVisibleOverlay(true)" after setting "false" it works(without crash), but already there is no overlay

skydoves commented 2 years ago

Hey @Arm63, this issue could be caused by a lot of reasons. I'd get more information below:

Arm63 commented 2 years ago

I'll create simple sample project with this issue and show you

skydoves commented 2 years ago

Thank you!

Arm63 commented 2 years ago

https://github.com/Arm63/Balloon_Issue

skydoves commented 2 years ago

You're using your own PopupWindow and this is a very tricky problem. You must check the popupWindow is correctly showing and attached to the current window properly. For checking this, the balloon uses a validation method canShowBalloonWindow. Maybe you need to check your own PopupWindow is valid with this kind of method.

skydoves commented 2 years ago

The WindowManager relevant issues for Balloon were already fixed in the past versions, you can also reference for building your own PopupWindow with the past issues below: https://github.com/skydoves/Balloon/issues?q=WindowManager

Arm63 commented 2 years ago

I have already checked this 2 (issue about WindowManager and canShowBalloonWindow), but can't find something to help me. P.S And I tried to open PopupWindow above of PopupWindows child and it happened without "bad token crash"

skydoves commented 2 years ago

I'm not sure what the main point caused this exception in your sample. Could you also try the codes below?

 val childViewFromPopupWindow = popupWindow.contentView.findViewById<TextView>(R.id.second_text)

if (ViewCompat.isAttachedToWindow(childViewFromPopupWindow)) {
            childViewFromPopupWindow.post {
                balloon.showAlignBottom(popupWindow.contentView)
            }
}

Essentially the sample code might throw BadTokenException if the content of your own popup window was not attached properly. Also, you must make sure that your own popup window is showing before displaying the balloon.

Arm63 commented 2 years ago

I pushed 2 commits https://github.com/Arm63/Balloon_Issue One of them is that state when I want to show balloon above of pop up windows child view (this works with crash even then child view of popupwindow is attached to window) And second is when I show pop up window above pop up window

Arm63 commented 2 years ago

Even if the library works with "popUpWindow" without "setVisibleOverlay(true)", on API levels 24 and 25 it doesn't work at all.

oradkovsky commented 1 year ago

Hey! Just my 2 cents to check reality pls:

Make sure you're using the setLifecycleOwner method and pass the correct context (Activity's context, not from Fragment or View).

View context - unless it is some bizarre case with services etc - will be activity anyways. Yes, activity and fragment are 2 different lifecycle owners, but view.getContext() will be the activity hosting either view directly, or view inside some sort of fragment - so should be no harm, please confirm?

skydoves commented 1 year ago

@oradkovsky If you can stick the balloon with your view, you should use View lifecycle owner. Anyway, this issue is a really rarely used case, so I'm closing this issue for now.