getExtractedText при неактивном предупреждении InputConnection на Android - PullRequest
117 голосов
/ 14 ноября 2011

Я получаю следующее предупреждение в своем logcat.

getExtractedText on inactive InputConnection

Я не могу найти причину этого. Пожалуйста, помогите

Ответы [ 10 ]

42 голосов
/ 31 марта 2013

Я столкнулся с подобной проблемой.Мой logcat:

W/IInputConnectionWrapper(21214): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(21214): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper(21214): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(21214): getTextAfterCursor on inactive InputConnection
...
I/Choreographer(20010): Skipped 30 frames!  The application may be doing too much work on its main thread.

Моя ситуация: у меня есть EditText для просмотра типов пользователей.EditText очищается, когда пользователь нажимает кнопку.Многие неактивные записи InputConnection выводятся, когда я быстро нажимаю кнопку.

Пример:

editText.setText(null);

Последняя строка в моем logcat выше дает отличное представление о том, что происходит.Конечно же, InputConnection перегружены запросами на очистку текста.Я попытался изменить код для проверки длины текста, прежде чем пытаться очистить его:

if (editText.length() > 0) {
    editText.setText(null);
}

Это помогает смягчить проблему, заключающуюся в том, что быстрое нажатие кнопки больше не вызывает поток предупреждений IInputConnectionWrapper.Однако это все еще подвержено проблемам, когда пользователь быстро переключается между набором чего-либо и нажатием кнопки или нажатием кнопки, когда приложение находится под достаточной нагрузкой и т. Д.

К счастью, я нашел другой способ очистки текста: Editable.clear () .При этом я вообще не получаю предупреждений:

if (editText.length() > 0) {
    editText.getText().clear();
}

Обратите внимание, что если вы хотите очистить все входные состояния, а не только текст (автотекст, автокап, многократный ввод, отмена), вы можете использовать TextKeyListener.clear (редактируемый e) .

if (editText.length() > 0) {
    TextKeyListener.clear(editText.getText());
}
14 голосов
/ 26 мая 2015

Обновление:

Причина, по которой я получал предупреждения InputConnection, была не в том, где я устанавливал текст (т. Е. В обратном вызове onTextChanged или afterTextChanged), - в том, что я использовал setText.

Я решил проблему, позвонив по номеру:

hiddenKeyboardText.getText().clear();
hiddenKeyboardText.append("some string");

Примечание. Я все еще выполняю вызов в обратном вызове afterTextChanged, хотя он также работает без предупреждений от ontextChanged.

Предыдущий ответ:

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

Часть открытого текста работает в соответствии с решением Джонсона выше. Однако сброс текста был проблематичным, и я получал предупреждения о входном соединении.

Первоначально мой onTextChanged(CharSequence s, ...) был определен следующим образом:

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (isResettingKeyboard)
        return;

    // ... do what needs to be done

    resetKeyboardString();

}

public void resetKeyboardString()
{
    isResettingKeyboard = true;

    hiddenKeyboardText.getText().clear();
    hiddenKeyboardText.setText(keyboardInitString);
    hiddenKeyboardText.setSelection(defaultKeyboardCursorLocation);

    isResettingKeyboard = false;
}

Когда вызывается onTextChanged(...), EditText находится в режиме только для чтения. Я не уверен, означает ли это, что мы не можем сделать больше, чем вызвать getText.clear() (вызовы setText(...) также вызывают предупреждения inputConnection).

Однако обратный вызов afterTextChanged(Editable s) является правильным местом для установки текста.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

Пока что это работает без каких-либо предупреждений.

7 голосов
/ 06 марта 2014

У меня была такая же проблема.Предупреждение появилось, когда на одной из моих EditTexts была активирована программная клавиатура, и активность потеряла фокус.

Что я сделал, чтобы скрыть клавиатуру в onPause ();

@Override
protected void onPause() {

    // hide the keyboard in order to avoid getTextBeforeCursor on inactive InputConnection
    InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

    inputMethodManager.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);

    super.onPause();
}
7 голосов
/ 22 августа 2012

Из справочных документов

http://developer.android.com/reference/android/view/inputmethod/InputConnection.html

Интерфейс InputConnection является каналом связи от InputMethod возвращается к приложению, которое получает входные данные. это используется для выполнения таких вещей, как чтение текста вокруг курсора, фиксация текста в текстовом поле и отправка необработанных ключевых событий в применение.

Кроме того, дальнейшее чтение показывает

getExtractedText (): Этот метод может не сработать, если входное соединение стало недействительным (например, сбой процесса), или клиенту требуется слишком много времени, чтобы ответ с текстом (ему дается пара секунд, чтобы вернуться) . В в любом случае возвращается ноль.

По-видимому, он также отслеживает изменения в таком тексте и оповещает об изменениях.

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

Если у вас нет никаких представлений, например, это происходит случайным образом в фоновом режиме, то я бы предположил, что это не проблема элемента пользовательского интерфейса, поэтому игнорируйте текстовые поля и тому подобное. Это может быть фоновый сервис, который хранит информацию в курсоре или запрашивает курсор.

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

Я бы рискнул предположить, что если вы не написали что-то конкретное вокруг этого, что кто-то использует журнал сообщений или, возможно, что-то из используемой вами библиотеки?

1 голос
/ 06 апреля 2015

Помимо ответа antoniom, убедитесь, что любые дальнейшие действия, которые необходимо выполнить, действительно выполняются после скрытия клавиатуры, поэтому, если вы спрятали клавиатуру, как показано ниже:

public void hideKeyboard() {
InputMethodManager inputMethodManager =(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
}

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

getWindow().getDecorView().post(new Runnable() {            
        @Override
        public void run() {
            finish(); //Sample succeeding code
     }
});
1 голос
/ 08 августа 2014

Решил эту проблему для себя, может быть, у вас такая же проблема.

Это было вызвано Объектом в HeaderView Адаптера списка .

Я накачал Вид , объявил Объект и надел на него TextWatcher .

View v = LayoutInflater.from(CONTEXT).inflate(R.layout.in_overscrollview, null);
Object= (Object) v.findViewById(R.id.OBJECT_ID);

Object.addTextChangedListener(new TextWatcher() {
        @Override
        public void afterTextChanged(Editable s) {
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after){
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        //Do my work
        //Update my view
        }
});

Добавил его в список Адаптер и встроил адаптер.

JobListView = (ListView) getListView().findViewWithTag("JOBLISTVIEWTAG");
JobListView.addHeaderView(v, null, false);
JobsAdapter = new IN_JOBS_ADAPTER(CONTEXT, ITEMS_FOR_ADATER);
ListView.setAdapter(JOBSadapter);

Все отлично, Наблюдатель за текстом работает.

НО если я когда-нибудь перестроил адаптер после первоначальной сборки.

JobsAdapter = new IN_JOBS_ADAPTER(CONTEXT, DIFFERENT_ITEMS_FOR_ADAPTER);
ListView.setAdapter(JOBSadapter);

То, что HeaderView тоже перестраивается.

Это предупреждение будет отображаться, потому что Объект был удален, а Наблюдатель за текстом все еще был настроен на его наблюдение.

Список Адаптер и Объект были заменены, и я предполагаю, что Наблюдатель текста выглядел иначе, когда это произошло.

Таким образом, предупреждение сработало, и чудом Наблюдатель текста находит HeaderView и Объект . Но он теряет фокус и записывает это предупреждение.

Использование

JOBSadapter.notifyDataSetChanged();

исправил проблему.

НО , если у вас есть Объект внутри Адаптера , и Наблюдатель текста присоединен к Объекту внутри Адаптера . Тогда вам, возможно, придется проделать немного больше работы.

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

Object.removeTextChangedListener();
* * Или тысяча семьдесят-девять
Object.addTextChangedListener(null);
0 голосов
/ 10 октября 2018

Скрыть программную клавиатуру перед очисткой EditText - предупреждения не будут отображаться.

Также, похоже, зависит от устройства .Я видел это только на Nexus 4 (Android 7.1).Нет предупреждений на эмуляторах (8.0, 7.1) или Nexus 5.

0 голосов
/ 16 февраля 2018

Ошибка в Logcat: getTextBeforeCursor при неактивном InputConnection

Решение: Скрыть клавиатуру ввода и запустить приложение.

0 голосов
/ 03 марта 2017

Я решил проблему с вставкой типа ввода в xml следующим образом: андроид: inputType = "нет | текст | textCapWords | textUri"

до этого был android: inputType = "text" Это решило мою проблему.

0 голосов
/ 11 марта 2016

У меня была эта проблема, когда мне пришлось изменить или получить текст из EditText, и он был сфокусирован.

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

Может быть, ваша проблема в другом.

...