This article contains the android. View. WindowManager $BadTokenException 4 kinds of situations:

  • 1.Unable to add window –token null is not valid; is your activity running

  • 2.Unable to add window –token null is not for an application

  • 3.Unable to add window — token android.os.BinderProxy@XXX is not valid; is your activity running

  • 4.Unable to add window — token android.app.LocalActivityManager$LocalActivityRecord @xxx is not valid; is your activity running

Case 1. Android. The WindowManager $BadTokenException: Unable to add the window – token null is not valid; is your activity running? Exception handling.

$BadTokenException: Unable to add window -- 

token null is not valid; is your activity running 

E/AndroidRuntime(1412): at android.view.ViewRootImpl.setView(ViewRootImpl.java:538) 

......
Copy the code

This exception is most commonly thrown in the use of the Popup Window component.

Reason: wrong in PopupWindow. ShowAtLocation (the findViewById (R.i d.m ain), Gravity. BOTTOM, 0, 0). Popwindow must be attached to a view, and in onCreate the view is not loaded yet. You must wait until the activity’s lifecycle functions are complete and the attached view is loaded before you can execute popWindow.

ShowAtLocation () can be changed like this:

Post (new Runnable() {@override public void run() {popwindow.showatlocation (mView, Gravity.CENTER, 0, 0); }});Copy the code

Conclusion: PopupWindow must be displayed in an event or a new thread is started to call it. You cannot display a PopupWindow directly in the onCreate method, otherwise the above error will always occur.

Reference:

Stackoverflow.com/questions/4…

Case 2. Android. The WindowManager $BadTokenException: Unable to add the window – token null is not the for an application? Exception handling.

$BadTokenException: Unable to add window -- 

token null is not for an application 

E/AndroidRuntime(1412): at android.view.ViewRootImpl.setView(ViewRootImpl.java:538) 

......
Copy the code

This exception is most commonly thrown in the use of an AlertDialog component.

New AlertDialog.Builder(getApplicationContext()) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("Warnning") .setPositiveButton("Yes", positiveListener) .setNegativeButton( "No", negativeListener) .create().show();Copy the code

The reason: New Alertdialog. Builder(McOntext); new AlertDialog.Builder(Context Context); But instead of using the Context obtained by getApplicationContext(), we must use an Activity, because only an Activity can add a form.

Solutions: To create a Dialog properly, fill the parameter in New AlertDialog.Builder(Context Context) with activity.this (Activity is the name of your Activity) or getActivity().

New Alertdialog.Builder (this) // This can be replaced with mainActivity.this or getActivity(). .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("Warnning") .setPositiveButton("Yes", positiveListener) .setNegativeButton( "No", negativeListener) .create().show();Copy the code

Reference:

Stackoverflow.com/questions/2…

Situation 3. Android. The WindowManager $BadTokenException: Unable to add window — token android.os.BinderProxy@XXX is not valid; is your activity running? Exception handling.

android.view.WindowManager$BadTokenException: Unable to add window -- 

token android.os.BinderProxy@4250d6d8 is not valid; is your activity running?

    at android.view.ViewRootImpl.setView(ViewRootImpl.java:698)

    ......

    at dalvik.system.NativeStart.main(Native Method)
Copy the code

The root cause of this problem is that the View to which the dialog is to be attached no longer exists. When the interface is destroyed and then pop out; Or when the interface jumps our view changes, the context that the dialog is attached to changes or the interface is not running.

Solution: The interface has been destroyed caused by the error can only determine whether the interface exists and then pop up.

// If (! isFinishing()) { alert.show(); }Copy the code

Reference:

Stackoverflow.com/questions/2…

Github.com/VKCOM/vk-an…

Scenario 4. Android. The WindowManager $LocalActivityRecord @ XXX is not valid; is your activity running? Exception handling.

android.view.WindowManager$BadTokenException: Unable to add window -- 

token android.app.LocalActivityManager$LocalActivityRecord@43e5b158

is not valid; is your activity running?  
Copy the code
TipDialog dialog = new TipDialog(xxx.this);Copy the code

Reason: The new dialog specifies this as the context that points to the current child Activity. However, child activities are created dynamically and cannot be guaranteed to last forever. The context of the parent Activity is stable, so there is a solution.

Solution: Replace context with getParent(). Note: To create dialog objects, the context must be an Activity, and if activityGroups are nested within activityGroups, use as many getParent() as possible.

TipDialog dialog = new TipDialog(getParent());Copy the code
// Modified code for one or more parent cases Activity Activity = testActivity. this; while (activity.getParent() ! = null) { activity = activity.getParent(); } TipDialog dialog = new TipDialog(activity) ;Copy the code

Reference:

Stackoverflow.com/questions/9…

Note: The reason for using getParent can be understood from the internal mechanics of ActivityGroup:

TabActivity’s parent class is ActivityGroup, and ActivityGroup’s parent class is Activity.

Therefore, from the point of view of Ams ActivityGroup no difference with normal Activity, its life cycle including standard start, stop, resume, destroy, etc., and the system only allows while allowing a ActivityGroup.

There is an important member variable inside the ActivityGroup, of type LocalActivityManager. The best feature of this class is that it has access to the main class of the application process, the ActivityThread class. The ActivityThread class is used by Ams to start or approve an Activity, and the LocalActivityManager class is meant to load different activities and control their different states. It is important to note that this is a load, not a start.

By launching, we generally mean that a process is created (if the application doesn’t often exist yet) to run the Activity. Loading simply means that the Activity is loaded as a normal class and an object of that class is created, without any of its functions being run. The process of loading an Activity object is completely invisible to AmS, and the embedded Activity only contributes to its contained Window. The different states of child activities are handled by moveToState.

Therefore, a child Activity is not like a normal Activity, it only provides a Window, so when creating a Dialog, you should use getParent to get the actual Activity of the ActivityGroup before adding a Dialog to the Activity.

Link: www.jianshu.com/p/4c5fafe08…