Исключение при фокусировке EditText в PopupWindow, запущенном на устройстве

17

Я разрабатываю окно PopUp для Android, и он работает, я добавил EditText и кнопку на том, что при работе в ADV эта работа работает правильно, работая на устройстве, когда я фокусируюсь на EditText, это бросает странный Исключение.

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

Я не знаю, имеет ли это значение, но я запускаю Galaxy Tab со входом Swype.

Теперь я прочитал спецификации 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
[...]

Проблема только в этом токене, но как я могу передать токен Activity?

Я также написал небольшой код для воспроизведения ошибки.

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);

Запуск на AVD все работает нормально, а на устройстве этот сбой и выбросить ошибку, о которой я упоминал.

Я обнаруживаю что-то новое, когда я в ландшафтном режиме, таких ошибок не возникает.

    
задан Marcos Vasconcelos 28.01.2011 в 16:09
источник
  • Это может быть полный выстрел в темноте, но, немного исследовав это, кажется, что эта проблема может быть вызвана тем, что вы используете Activity.getApplicationContext в качестве контекста. Этот поток дает вам решение, если это действительно ваша проблема. groups.google.com/group/android-developers/browse_thread/thread/... –  Mia Clarke 09.02.2011 в 15:46
  • Я пробовал даже с большим количеством контекстов (от кнопки, от Activity, application) той же самой ошибки на всех. –  Marcos Vasconcelos 10.02.2011 в 20:53
  • @Marcos Vasconcelos, у меня с вами такая же проблема, и, похоже, это не код, но устройство вызывает сбой. и я проверил некоторые вкладки and phone andsamgs samsumg, большинство из которых будет разбиваться. Я хочу знать, что вы решили эту проблему. или что мы должны делать. –  DiveInto 29.08.2011 в 10:00
  • @Marcos, нашли ли вы решение своей проблемы? У меня есть аналогичный (попытка добавить подменю в меню всплывающего окна), за исключением того, что он не работает и на эмуляторе ... Невозможно найти какое-либо решение в любом месте, мне было бы интересно узнать, решили ли вы его –  Guillaume 02.12.2011 в 01:23
  • @MarcosVasconcelos У меня такая же проблема, но в моем случае edittext находится в веб-обзоре, нашли ли вы какое-либо решение –  Muhammad Babar 10.10.2013 в 13:09

7 ответов

6

Спасибо, TheRedPill! У меня была такая же проблема с EditText внутри PopupWindow, ведущей себя грубо. Он работал на Samsung Galaxy S3, HTC One X, но разбился на Huawei MediaPad FHD 10. Как только я начал редактировать приложение, он разбился.

Ваше решение:

editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);

Решил проблему для меня.

Трассировка стека:

08-15 15:49:03.690: ERROR/AndroidRuntime(8692): FATAL EXCEPTION: main
    android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] 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.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)
    
ответ дан kosiara - Bartosz Kosarzycki 15.08.2013 в 14:57
  • ваш человек +1 –  Tofeeq 26.11.2013 в 12:04
  • Спасибо, вы сохранили мой код: D –  sdelvalle57 11.08.2016 в 22:39
  • это решило мою проблему –  HendraWD 18.10.2016 в 10:16
  • InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS не работает на всех клавиатурах. Для меня он не работал на стандартных клавиатурах устройств Samsung. Мне пришлось использовать InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD, чтобы избежать предложений на таких устройствах. –  Varun Bhatia 27.11.2016 в 08:31
4

Причина:

Я отслеживаю причину ошибки вплоть до автоматического исправления правописания на некоторых телефонах (Moto Droid Razr и несколько других Moto Phones) и некоторых android Rom (например, некоторые CM7 и CM7.1 ROMS). Если в тексте есть слово, которое неправильно написано, и текстовый курсор зависает в тексте или рядом с ним, ОС Android попытается автоматически вызвать клавиатуру и попытаться предоставить предложения по правильному написанию.

На большинстве устройств поле с правильной настройкой по умолчанию отображается только как однострочный сегмент над клавиатурой. Однако на некоторых пользовательских ПЗУ (CM7 - это один из них, с которым я часто сталкиваюсь) и некоторые устройства (Droid Razr), появляется дополнительный раскрывающийся список:

Посмотрите на это изображение того, как выглядит автозаполнение всплывающего окна (извините, что недостаточно для вставки изображения)

Я очень подозреваю, что раскрывающийся список с автоматическим исправлением также реализуется как всплывающее окно, и он пытается использовать текущее всплывающее окно (такое, которое содержит EditText с неправильным произношением) в качестве корневого представления, и пытаясь получить windowToken из корневого представления.

Поскольку всплывающее окно не является традиционным представлением, я предполагаю, что он не может дать правильное окноToken другим представлениям, которые их запрашивают, что приводит к ошибке.

Решения:

1) Самый простой способ решить эту проблему - использовать Dialog вместо всплывающих окон. Их API очень похож, и в моих случаях довольно легко заменить PopupWindow с помощью Dialog.

Например:

Старый код:

    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);

Новый код:

    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) Второй подход сложнее, но может быть подходящим, если замена PopupWindow для Dialog не выполнима, это для пользователя фрагменты вместо PopupWindows. Существует много хороших фрагментов учебных пособий , поэтому я не буду беспокоиться о том, как это сделать в этом сообщении.

3). В крайнем случае, например, как многочисленные плакаты, упомянутые выше, вы можете отключить автоматический текст текста на поля EditText внутри PopupWindwow, чтобы устранить эту проблему. Однако это приводит к ужасному опыту пользователей, поскольку многие пользователи (и клавиатуры, такие как swype) полагаются на автоматическую коррекцию, поэтому это приведет к отключению пользователя от вашего приложения.

Надеюсь, это поможет другим, кто сталкивается с этой проблемой. Я ударился головой о клавиатуру в течение дня, прежде чем, наконец, решил попробовать подход «Диалог», который, к моему удивлению, довольно легко заменил. Удачи вам

    
ответ дан gordon1hd1 07.05.2014 в 03:43
3

Я попытался запустить ваш код, но все работает отлично для меня ... Вот тестовый класс, который я написал:

public class TestActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button btn = (Button) findViewById(R.id.testBtn);
        btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v)
            {
                showPopup();
            }
        });
    }


    private void showPopup()
    {
        PopupWindow window = new PopupWindow(this);
        window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
        window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);

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

        EditText text = new EditText(this);
        text.setText("Touch it, it doesn't crash");

        window.setContentView(text);
        window.showAtLocation(text, Gravity.NO_GRAVITY, 30, 30);
    }
}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <Button
        android:id="@+id/testBtn"
        android:text="Popup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

Возможно, вы пытались запустить всплывающий код в функции onCreate ()? Если я это сделаю, он выбрасывает то же Исключение, что и ваше, но это нормально, так как при вызове onCreate () активность еще не полностью инициализирована.

(Я тоже пробовал на вкладке Galaxy, но без ввода swype)

    
ответ дан Dalmas 04.02.2011 в 18:18
  • На самом деле, я вызываю это из события, ваш код выдает одно и то же Исключение, но ТОЛЬКО на устройстве, это странная часть. Ty –  Marcos Vasconcelos 04.02.2011 в 18:25
  • Это странно, я не понимаю ... для меня это работает также и на AVD, как на моей Galaxy Tab. –  Dalmas 04.02.2011 в 18:35
  • Также отлично работает на моих желаниях Galaxy S и HTC –  Dalmas 04.02.2011 в 18:37
  • Я снова попытался с кодом, той же ошибкой, даже без Swype –  Marcos Vasconcelos 10.02.2011 в 20:52
  • Я снова проверил этот код, и в ландшафтном режиме он не сработает. –  Marcos Vasconcelos 24.02.2011 в 22:37
2
EditText text = new EditText(activity);
text.setText("Dont touch, this crash!");

это действительно является причиной исключения.

, когда мы привязываем EditText к некоторому тексту, который выпадает при щелчке при появлении виртуальной клавиатуры.

Но тот же код отлично работает, когда мы не привязываем EditText

EditText text = new EditText(activity);

Хотя я столкнулся с такой же ошибкой и не смог разобраться до сих пор ....

Просто приложив усилия, чтобы сосредоточиться на линии создания проблем ...

Может ли любой орган предложить, почему itz ведет себя так и как исправить эту проблему.

Thankx

    
ответ дан DeltaCap 09.05.2012 в 05:36
0

Edited

попробуйте сделать это, создайте новый класс, скажем Popupcls

  public class PopUpFlag {
        private PopupWindow pw;

    public void initiatePopupWindow(Activity ctx) {
     LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View layout = inflater.inflate(R.layout.popupprofile,  (ViewGroup) ctx.findViewById(R.id.popup_element));
    EditText ettext = (EditText) layout.findViewById(R.id.edit);
    pw = new PopupWindow(layout, 300, 400, true);
    pw.showAtLocation(layout, Gravity.BOTTOM, 0, 0);
    }

Теперь в вашей деятельности, если вам нужно всплывающее окно, когда кнопка всплывающего окна нажимает так, как это написано

popupbtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                PopUpFlag puf=new PopUpFlag();
                puf.initiatePopupWindow(YourActivityName.this);
            }
        });

Я надеюсь, что это поможет

    
ответ дан praveenb 29.04.2011 в 22:29
  • На самом деле, эта строка находится за пределами моего класса Activity, но эта активность является ссылкой на нее. И я пробовал с большим количеством контекстов –  Marcos Vasconcelos 29.04.2011 в 22:31
0

Я также получил ту же ошибку, когда edittext в моем popupwindow уже присутствовал в тексте, и текст не был словарным словом (например, название города). Когда я нажимаю между текстом и бумом! Я получил исключение. Я решил это, создав edittext, не отображая автоматически правильные предложения:

android:inputType="textNoSuggestions"
    
ответ дан Sumit 04.03.2013 в 12:57
0

Сбой происходит в EditText, помещенном в WindowManager, когда пользователь нажимает на слово, подчеркнутое красным. Такое подчеркнутое слово означает, что оно не существует в словаре. При нажатии OS пытается отобразить поп с ближайшими совпадающими словами из словаря и сбой, так как такое всплывающее окно не может быть прикреплено к окну из-за плохого исключения токена.

Только следующее решение, казалось, работало для меня программно

//assume an EditText object with name myEditText
myEditText.setInputType(myEditText.getInputType() | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
  

InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS работает не так, как ожидалось, на всех клавиатурах, тогда как InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD имеет тот недостаток, что он также отключает переключение языка на клавиатуре и жестов салфетки для добавления текста.

    
ответ дан Varun Bhatia 10.11.2016 в 06:06