17

I've been struggling to find out the reason of this exception for a while, I've never been able to reproduce myself but some of my customers are experiencing it. It only happens on Android 6.0.1, and since the crash occurrs within the SDK itself it's quite hard to figure out how it happens.

Other solutions regarding this problems have not helped, such as:

window manager bad token exception

"android.view.WindowManager$BadTokenException: Unable to add window" on buider.show()

I am using DialogFragments and AlertDialogs, I guess it could be the core issue but it just doesn't add up since it only affects Marshmallow users.

Fatal Exception: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
       at android.view.ViewRootImpl.setView(ViewRootImpl.java:849)
       at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:337)
       at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
       at android.widget.PopupWindow.invokePopup(PopupWindow.java:1329)
       at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1077)
       at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1035)
       at com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup.show(FloatingToolbar.java:561)
       at com.android.internal.widget.FloatingToolbar.show(FloatingToolbar.java:212)
       at com.android.internal.view.FloatingActionMode$FloatingToolbarVisibilityHelper.updateToolbarVisibility(FloatingActionMode.java:411)
       at com.android.internal.view.FloatingActionMode$1.run(FloatingActionMode.java:65)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:158)
       at android.app.ActivityThread.main(ActivityThread.java:7224)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Community
  • 1
  • 1
Lucas Arrefelt
  • 3,879
  • 5
  • 41
  • 71
  • If your app's in production, you must fix this asap. Localize the error and surround with a try/catch where catch will just silently fail - which is 10 times better than the app crashing. I'm sorry if I'm of not much help, since I do not know why this is happening, but I'm just offerin a piece of advice in general. – Vucko Jul 19 '16 at 20:32
  • I totally agree, however it's the localization part thats hard since the stacktrace doesn't really give me much pointers on where it actually happens. I'm just hoping that someone here might know what could cause it which would ease my investigation – Lucas Arrefelt Jul 19 '16 at 20:36
  • The stacktrace is talking about action mode, so that's what you should focus on. What can your users do to get the action mode to come up in the toolbar? May something weird like: user can select text somewhere, but the user touch might also invoke a new activity, so the selection and new activity happen at the same time. – kris larson Jul 19 '16 at 20:46
  • Including the code that shows your fragments and dialogs would be useful. – Jeffrey Blattman Jul 19 '16 at 20:50
  • @krislarson Thanks, that was my initial thought too and probably where I will continue to look. Floating toolbar is new in Marshmallow so it obviously has something to do with it – Lucas Arrefelt Jul 19 '16 at 20:58
  • If you might actually get in contact with some of the users which had encountered this, and ask them what **exactly** they did when they encountered this error. – Vucko Jul 19 '16 at 21:19
  • @krislarson Thank you for pointing me to the action mode, posted solution. – Lucas Arrefelt Aug 24 '16 at 09:22

1 Answers1

26

So after aquiring a Samsung device (S6) and being able to reproduce this problem I came up with the solution described below.

The error itself originates from the floating toolbar and action modes that was added in Marshmallow. When selecting text on a marshmallow device, something like this comes up:

floating toolbar

If the user then navigates to another activity (e.g. back key) without closing the floating toolbar, the app crashes on Samsung devices. It is basically trying to add the floating toolbar again to the upcoming activity.

More on floating toolbar: https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-text-selection

So the solution is to manage the action mode lifecycle and make sure it finishes before any new activity is started. I've got a base activity class that all my activites inherits from, so it made most sense to add the solution there.

public class BaseActivity extends AppCompatActivity {

    private ActionMode mActionMode;

    /**
     * Store action mode if it is started
     * @param mode
     */
    @Override
    public void onActionModeStarted(ActionMode mode) {
        super.onActionModeStarted(mode);
        mActionMode = mode;
    }

    /**
     * When activity is paused, make sure action mode is ended properly.
     * This check would feel better to have in onDestroy(), but that seems to be
     * too late down the life cycle and the crash keeps on occurring. The drawback 
     * of this solution is that the action mode is finished when app is minimized etc.
     */
    @Override
    protected void onPause() {
        super.onPause();
        endActionMode();
    }

    /**
     * Makes sure action mode is ended
     */
    private void endActionMode() {
        if (mActionMode != null) {
            mActionMode.finish(); /** immediately calls {@link #onActionModeFinished(ActionMode)} */
        }
    }

    /**
     * Clear action mode every time it finishes.
     * @param mode
     */
    @Override
    public void onActionModeFinished(ActionMode mode) {
        super.onActionModeFinished(mode);
        mActionMode = null;
    }
}
EricRobertBrewer
  • 1,750
  • 1
  • 22
  • 25
Lucas Arrefelt
  • 3,879
  • 5
  • 41
  • 71
  • Oh crap, I have to check and see if that can happen with my app – kris larson Aug 24 '16 at 11:29
  • 1
    The main views of the app I'm working on is based on WebViews. That made this bug much more severe for me since the users have much content that is selectable and therefore is more prone to experience the bug – Lucas Arrefelt Aug 24 '16 at 12:31
  • Been trying to remove this bug! Please star the issue on Android tracker so the Android team fix it https://code.google.com/p/android/issues/detail?id=208906 – Tim Kist Oct 05 '16 at 14:52
  • @TimKist I've added a [comment](https://code.google.com/p/android/issues/detail?id=208906#c12) to the bug report. I doubt it's something that the AOSP can fix, but Samsung might have fixed it their Nougat updates (which are starting to roll out). You'll always need to workaround this for Samsung running 6.0.1 though. – fingertricks Mar 02 '17 at 14:35
  • We've now updated a Samsung S7 Edge to Nougat (7.0) and can no longer reproduce this bug, so it appears that Samsung have fixed it. – fingertricks Mar 02 '17 at 19:23
  • I keep getting similar crashes on Android 9 on Samsung devices... I don't think they really fixed the problem once and for all – MatPag Apr 20 '20 at 13:03