getExtractedText про неактивне попередження InputConnection на android


129

Я отримую таке попередження у своїй реєстраційній системі.

getExtractedText on inactive InputConnection

Я не можу знайти причину. Будь ласка, допоможіть


4
Я не розумію, що в цьому питанні є неоднозначним / невиразним / неповним? Я отримую це попередження у своїй реєстраційній системі під час роботи свого додатка, я хочу знати причину цього попередження.
pankajagarwal

2
Я також бачу це у своїй заявці, що я розробляю, і я не маю уявлення, звідки це походить або чому. Якщо хтось коли-небудь дізнається, будь ласка, опублікуйте коментар. Він фактично показує багато різних попереджень, крім "getExtractedText". Я також бачу: "beginBatchEdit", "endBatchEdit", "getTextBeforeCursor" та багато іншого.
проміжок

1
чи модератори розглядають це питання. Якщо ні, то слід, тому що якщо вони все ще вважають це питання невиразним та неоднозначним навіть після 14 оновлень, то я не знаю, що сказати
pankajagarwal

Я згоден, це проблема, яку я також повинен вирішити. Я не маю уявлення про причину.
JonWillis

3
Який у вас код, що викликає цю помилку?
Білл Ящірка

Відповіді:


44

Я зіткнувся з подібним питанням. Мій логін:

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, на який входять користувачі. Очищення редагування тексту видаляється, коли користувач натискає кнопку. Багато неактивних записів 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());
}

1
Я отримував попередження IInputConnectionWrapper, і в моєму додатку було майже ANR, метод clear () працював для мене ... надзвичайно дивна помилка, перш ніж я встановлював setText ("");
поле

17

Оновлення:

Причина, коли я отримував попередження 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();

    // ... 
}

Поки що це працює без жодних попереджень.


У мене була така ж проблема. Я зрозумів, що, хоча ваше рішення змушує затримати попередження InputConnection, я помітив, що afterTextChangedметод застосовується hiddenKeyboardText.getText().clear();як і далі hiddenKeyboardText.append("some string");, і цей факт також слід враховувати. +1 від мене!
Нік

@Nick true - важливо забезпечити, щоб він if (isResettingKeyboard) return;був на вершині ...
ahash

7

З довідкових документів

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

Інтерфейс InputConnection - це канал зв'язку від InputMethod назад до програми, яка отримує свій вхід. Він використовується для виконання таких речей, як читання тексту навколо курсору, введення тексту в текстове поле та надсилання непередбачених ключових подій у додаток.

Крім того, подальше читання показує

getExtractedText (): Цей метод може виявитися невдалим, якщо вхідне з'єднання стало недійсним (наприклад, зрив його процесу) або клієнт забирає занадто багато часу, щоб відповісти текстом (йому потрібно дати кілька секунд, щоб повернутися) . В будь-якому випадку нуль повертається.

Схоже, він також відстежує зміни в такому тексті та попереджає зміни.

Щоб вирішити проблему, вам доведеться вивчити будь-які запити до бази даних, які ви робите, можливо, навколо listViews або списків у макеті.

Якщо у вас немає переглядів, наприклад, це відбувається випадковим чином на задньому плані, то я б припустив, що це не проблема елемента інтерфейсу, тому ігноруйте текстові поля тощо. Це може бути фонова служба, яка зберігає інформацію в курсорі або запитує курсор.

Також проблема виникає у вашому додатку? або, можливо, хтось інший, який ви встановили нещодавно. Перерахуйте повний слід logCat. Хтось може розпізнати проблему.

Я б загрожував припущенням, що якщо ви не написали щось конкретно навколо цього, що його хтось видаляє, або, можливо, те, що використовується бібліотека?


1
дякую, я роблю запити на db, але, як не дивно, це попередження не з’являється під час запуску програми на емуляторі, так що насправді це може бути пов’язано з іншим додатком, встановленим на моєму пристрої. Поглянемо в цей напрямок
pankajagarwal

Я думаю, що останній logCat показує, що ваші повідомлення відрізняються від інших програм, відфільтровані. Не використовували його достатньо, щоб підтвердити це. Ви можете створити нову порожню програму та спостерігати за журналом кота, щоб побачити, чи не відбулася помилка, яка б усунула вашу програму. від того, що це питання.
Еміль

@frieza не обов'язково інший додаток. Я додав ArrayAdapter з sqlite, і тепер отримую це попередження і по телефону. Я думаю, ви не бачите помилок на емуляторі, оскільки він повільний, а пороги продуктивності відключаються як наслідок.
alandarev

7

У мене була така ж проблема. Попередження з’явилося, коли в одному з моїх функцій була активована м'яка клавіатура, 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();
}

2
Це відповідь гаразд. Переконайтесь, що ви заховали клавіатуру, перш ніж ви перейдете від активності, яку ви зараз маєте на екрані.
Габор

1

Вирішили це питання для себе, можливо, у вас є та сама проблема.

Це було викликано об'єктом в 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);

Все добре, працює Text Watcher .

АЛЕ якщо я коли-небудь перебудував адаптер після початкової збірки.

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

Цей HeaderView також перебудований.

Це попередження відображатиметься, оскільки Об'єкт було видалено, а Дивитель тексту все ще налаштований на його спостереження.

Список адаптер і Object були замінені, і я припускаю , що текст Watcher дивиться в іншу сторону , коли це сталося.

Тож попередження зникає і дивом Дивитель тексту знаходить HeaderView та Об'єкт . Але він втрачає фокус і записує це попередження.

Використання

JOBSadapter.notifyDataSetChanged();

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

АЛЕ якщо у вас є Об'єкт всередині адаптера , а " Текстовий спостерігач" приєднаний до " Об'єкту" всередині адаптера . Тоді вам може знадобитися зробити трохи більше роботи.

Спробуйте вийняти слухача та приєднати його знову після виконання будь-якої роботи, яку ви можете робити.

Object.removeTextChangedListener();

або

Object.addTextChangedListener(null);

1

Окрім відповіді на антоніому, переконайтеся, що будь-які подальші дії, які потрібно зробити, дійсно виконуються після приховування клавіатури, тому якщо ви приховали клавіатуру, як описана нижче:

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

0

У мене була ця проблема, коли мені довелося змінювати або отримувати текст з EditText, і це було зосереджено.

Тому перш ніж змінювати або отримувати з нього, я закрив клавіатуру і виправляю її.

InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

Можливо, ваша проблема інша.


0

Я вирішив свою проблему з введенням типу вводу в xml, як це: android: inputType = "жоден | текст | text | textCapWords | textUri"

до цього був android: inputType = "text" Це вирішило мою проблему.


3
Нічого не зробив для мене.
DSlomer64

0

Помилка в Logcat: getTextBeforeCursor при неактивному InputConnection

Рішення: прихойте клавіатуру введення та запустіть програму.


0

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

Крім того, схоже, що це пристрій . Я бачив це лише на Nexus 4 (Android 7.1). Немає попереджень про емулятори (8.0, 7.1) або Nexus 5.


0

Моя проблема була викликана встановленням видимості EditTextдо, GONEа потім негайно встановленням його VISIBLEщоразу, коли користувач вводив символ, оскільки я виконував перевірку на вході кожного разу, коли текст змінювався, а в деяких випадках перегляд потрібно було приховати.

Таким чином, рішення уникає встановлення видимості View або Layout на GONE між оновленнями інтерфейсу користувача або станами, оскільки це EditTextможе втратити фокус


0

Якщо вирішити ту саму проблему і вирішити її, перетворячи мій віджет без громадянства на станджет, ви можете спробувати його

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.