Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception when focusing a EditText in a PopupWindow running on Device

I'm developing a PopUp window for Android, and it's working, I added a EditText and a Button on that, when running on ADV this work properly, while running on device, when I focus on the EditText this throws a weird Exception.

android.view.WindowManager$BadTokenException: Unable to add window - - token android.view.ViewRoot&48163b18 is not valid; is your active running?

I don't know if it matters, but I'm running on a Galaxy Tab with Swype input.

Now I read the specs of the Window.showAtLocation

public void showAtLocation (View parent, int gravity, int x, int y)

Display the content view in a popup window at the specified location. If the popup window cannot fit on screen, it will be clipped. [...]

Parameters
parent  a parent view to get the getWindowToken() token from
[...]

The problem is just in that token, but how do I pass the Activity token to it?

I also wrote a small code to reproduce the error.

PopupWindow window = new PopupWindow(activity);
window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);

window.setTouchable(true);
window.setFocusable(true);

EditText text = new EditText(activity);
text.setText("Dont touch, this crash!");

window.setContentView(text);
window.showAtLocation(arg0, Gravity.NO_GRAVITY, 10,10);

Running on AVD all works fine, while on device this crash and throw the error I mentioned.

I discover something new, when I'm in landscape mode this errors don't occurs.

like image 373
Marcos Vasconcelos Avatar asked Jan 28 '11 15:01

Marcos Vasconcelos


People also ask

What is the basic use of EditText control?

XML Attributes of Edittext in AndroidUsed to set size of the text. Used to set color of the text. Used to set style of the text. For example, bold, italic, bolditalic, etc.

What is EditText control?

A EditText is an overlay over TextView that configures itself to be editable. It is the predefined subclass of TextView that includes rich editing capabilities.


2 Answers

Thank you, TheRedPill! I had the same problem with EditText inside PopupWindow behaving stragely. It worked on Samsung Galaxy S3, HTC One X but crashed on Huawei MediaPad FHD 10. As soon as I started editing the application crashed.

Your solution:

editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);

Solved the issue for me.

The stack-trace was:

08-15 15:49:03.690: ERROR/AndroidRuntime(8692): FATAL EXCEPTION: main
    android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@417eefa8 is not valid; is your activity running?
    at android.view.ViewRootImpl.setView(ViewRootImpl.java:585)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:326)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
    at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
    at android.view.Window$LocalWindowManager.addView(Window.java:547)
    at android.widget.PopupWindow.invokePopup(PopupWindow.java:988)
    at android.widget.PopupWindow.showAtLocation(PopupWindow.java:845)
    at android.widget.PopupWindow.showAtLocation(PopupWindow.java:809)
    at android.widget.Editor$PinnedPopupWindow.updatePosition(Editor.java:2147)
    at android.widget.Editor$PinnedPopupWindow.show(Editor.java:2104)
    at android.widget.Editor$SuggestionsPopupWindow.show(Editor.java:2349)
    at android.widget.Editor.showSuggestions(Editor.java:1647)
    at android.widget.Editor$1.run(Editor.java:1546)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4745)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)
like image 180
kosiara - Bartosz Kosarzycki Avatar answered Oct 12 '22 06:10

kosiara - Bartosz Kosarzycki


The cause:

I trace the cause of the error down to the spelling auto-correct behavior on some phones (Moto Droid Razr and few other Moto Phones) and some android Rom (like some CM7 and CM7.1 ROMS). If the text contain a word that is incorrectly spell, and the text cursor is hovering in or near the text, the android OS will try automatically bring up the keyboard and try to provide suggestions on a correct spelling.

On most devices, the auto correct suggestion box only appear as a one line segment above the keyboard. However on some custom ROMs (CM7 being one I seem a lot happening to) and some devices (Droid Razr), there is an additional drop down selection box that appear :

See this image of what the auto-correct popup looks like (sorry not enough rep to insert image)

I highly suspect that the auto correct drop-down list is also implemented as a popup window, and it is trying to use the current popup (the one containing the EditText with the mis-spell word) as the root view, and trying to get the windowToken from the root view.

Since the popup itself is not a traditional view, I am assuming it is unable to give the correct windowToken to other views who are asking for them, therefore leading to the error.

The Solutions:

1) The easiest way I been able to get around this problem is by using Dialog instead of Popup windows. Their API is really similar and in my cases are fairly easy to replace PopupWindow using Dialog.

For example:

Old code:

    LayoutInflater inflater = (LayoutInflater) parentActivity.getLayoutInflater();
    View mainView = parentActivity.findViewById(R.id.main_calendar_fragment);
    updateEventPopupWindow = new PopupWindow(inflater.inflate(
            R.layout.add_event_fragment, null, false), metrics.widthPixels, metrics.heightPixels, true);
    updateEventPopupWindow.setBackgroundDrawable(new BitmapDrawable());
    updateEventPopupWindow.showAtLocation(mainView, Gravity.CENTER, 0, 0);

New code:

    LayoutInflater inflater = (LayoutInflater) parentActivity.getLayoutInflater();
    View mainView = parentActivity.findViewById(R.id.main_calendar_fragment);       
    updateEventDialog = new Dialog(parentActivity, android.R.style.Theme_NoTitleBar);
    updateEventDialog.setContentView(inflater.inflate(R.layout.add_event_fragment, (ViewGroup) mainView, false));
    updateEventDialog.show();

2) The second approach is harder, but might be a suitable if PopupWindow to Dialog replacement is not doable, is to user Fragments in place of PopupWindows. There are many good fragment tutorials out there, so I won't bother to go over how to do this in this post.

3) As a last resort, like multiple posters mentioned above, you can turn-off text auto correct on the EditText fields inside the PopupWindwow to side step this problem. However this lead to horrible user experiences, since many users (and keyboards like swype) relies on auto-correct, doing this will likely drive user away from your application.

Hope this helps other out there who are facing this problem. I banged my head against the keyboard for over a day before finally decided to try the Dialog approach, which to my surprise was fairly easy to swap out. Best of luck to you

like image 37
gordon1hd1 Avatar answered Oct 12 '22 08:10

gordon1hd1