getExtractedText o nieaktywnym ostrzeżeniu InputConnection w systemie Android

127

W moim logcat'ie pojawia się następujące ostrzeżenie.

getExtractedText on inactive InputConnection

Nie potrafię znaleźć przyczyny takiego stanu rzeczy. Proszę pomóż

pankajagarwal
źródło
4
Nie rozumiem, co jest niejednoznaczne / niejasne / niekompletne w tym pytaniu? To ostrzeżenie pojawia się w moim logcatie podczas uruchamiania aplikacji. Chcę poznać przyczynę tego ostrzeżenia.
pankajagarwal
2
Widzę to również w mojej aplikacji, którą tworzę i nie mam pojęcia, skąd się bierze i dlaczego. Jeśli ktoś się kiedykolwiek dowie, napisz komentarz. W rzeczywistości pokazuje wiele różnych ostrzeżeń innych niż „getExtractedText”. Widzę też: „beginBatchEdit”, „endBatchEdit”, „getTextBeforeCursor” i wiele innych.
obejmuje
1
czy moderatorzy przyglądają się temu pytaniu. Jeśli nie, to powinni, ponieważ jeśli nadal uważają to pytanie za niejasne i dwuznaczne, nawet po 14 głosach uprzywilejowanych, to nie wiem, co powiedzieć
pankajagarwal
Zgadzam się, to jest problem, którym też muszę się zająć. Nie mam pojęcia o przyczynie.
JonWillis,
3
Jaki masz kod, który powoduje ten błąd?
Bill the Lizard

Odpowiedzi:

44

Wpadłem na podobny problem. Mój 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.

Moja sytuacja: mam widok EditText, do którego wpisuje użytkownik. EditText zostaje wyczyszczony, gdy użytkownik naciśnie przycisk. Wiele nieaktywnych wpisów InputConnection wypływa, gdy szybko naciskam przycisk.

Dawny:

editText.setText(null);

Ostatni wiersz w moim logcat powyżej zapewnia doskonałe wskazanie tego, co się dzieje. Rzeczywiście, InputConnection jest przytłoczone żądaniami wyczyszczenia tekstu. Próbowałem zmodyfikować kod, aby sprawdzić długość tekstu, zanim spróbowałem go wyczyścić:

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

Pomaga to złagodzić problem, ponieważ szybkie naciśnięcie przycisku nie powoduje już strumienia ostrzeżeń IInputConnectionWrapper. Jednak jest to nadal podatne na problemy, gdy użytkownik szybko przełącza się między wpisywaniem czegoś i naciskaniem przycisku lub naciska przycisk, gdy aplikacja jest wystarczająco obciążona itp.

Na szczęście znalazłem inny sposób na wyczyszczenie tekstu: Editable.clear () . Dzięki temu w ogóle nie dostaję ostrzeżeń:

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

Zauważ, że jeśli chcesz wyczyścić cały stan wejściowy, a nie tylko tekst (autotekst, autocap, multitap, undo), możesz użyć TextKeyListener.clear (Editable e) .

if (editText.length() > 0) {
    TextKeyListener.clear(editText.getText());
}
Johnson Wong
źródło
1
Otrzymywałem również ostrzeżenia IInputConnectionWrapper i moja aplikacja otrzymała prawie ANR, metoda clear () zadziałała dla mnie ... super dziwny błąd, zanim ustawiłem setText ("");
pudełko
17

Aktualizacja:

Powodem, dla którego otrzymywałem ostrzeżenia InputConnection nie było to, gdzie ustawiałem tekst (tj. W onTextChangedwywołaniu zwrotnym lub afterTextChanged) - to dlatego, że używałem setText.

Omówiłem ten problem, dzwoniąc pod numer:

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

Uwaga: nadal wykonuję połączenie w afterTextChangedwywołaniu zwrotnym, chociaż działa również bez ostrzeżeń ontextChanged.

Poprzednia odpowiedź:

Otrzymywałem również identyczne wiadomości w logcat, chociaż mój scenariusz był nieco inny. Chciałem przeczytać każdy znak, który pojawił się w EditText (lub złożone znaki / wklejony tekst), a następnie zresetować ten EditText do domyślnego ciągu inicjalizacyjnego.

Część jawna działa zgodnie z powyższym rozwiązaniem Johnsona. Jednak resetowanie tekstu było problematyczne i otrzymywałem ostrzeżenia o połączeniu wejściowym.

Początkowo mój onTextChanged(CharSequence s, ...)został zdefiniowany następująco:

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

Kiedy onTextChanged(...)jest wywoływana, EditText jest w trybie tylko do odczytu. Nie jestem pewien, czy oznacza to, że nie możemy zrobić nic więcej niż wywołanie getText.clear()tego ( setText(...)wywołania powodują również ostrzeżenia inputConnection).

Jednak callback afterTextChanged(Editable s)jest właściwym miejscem do ustawienia tekstu.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

Jak dotąd działa to bez żadnych ostrzeżeń.

ahash
źródło
Ja też miałem ten sam problem. Uświadomiłem sobie, że chociaż twoje rozwiązanie powoduje zniknięcie ostrzeżeń InputConnection, zauważyłem, że afterTextChangedmetoda jest zarówno włączona, hiddenKeyboardText.getText().clear();jak i włączona hiddenKeyboardText.append("some string");, i ten fakt również należy wziąć pod uwagę. +1 ode mnie!
Nick
@Nick true - ważne, aby upewnić się, że if (isResettingKeyboard) return;jest na szczycie ...
ahash,
7

Z dokumentów pomocy

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

Interfejs InputConnection to kanał komunikacyjny z metody InputMethod z powrotem do aplikacji, która otrzymuje dane wejściowe. Służy do wykonywania takich czynności, jak czytanie tekstu wokół kursora, zatwierdzanie tekstu do pola tekstowego i wysyłanie nieprzetworzonych zdarzeń klawiszy do aplikacji.

Ponadto dalsze czytanie pokazuje

getExtractedText (): Ta metoda może się nie powieść, jeśli połączenie wejściowe stało się nieprawidłowe (na przykład awaria procesu) lub klient zbyt długo odpowiada za pomocą tekstu (zwraca kilka sekund) . W obu przypadkach zwracana jest wartość null.

Wydaje się również, że monitoruje zmiany w takim tekście i ostrzega o zmianach.

Aby znaleźć problem, musisz zbadać wszelkie zapytania do bazy danych, które tworzysz, na przykład wokół listViews lub list w układzie.

Jeśli nie masz żadnych widoków, na przykład dzieje się to losowo w tle, sugerowałbym, że nie jest to problem z elementem interfejsu użytkownika, więc zignoruj ​​pola tekstowe i tym podobne. Może to być usługa działająca w tle, która przechowuje informacje w kursorze lub żąda kursora.

Czy problem wynika również z Twojej aplikacji? a może ktoś inny, kogo niedawno zainstalowałeś. Wyświetl pełny ślad logCat. Ktoś może rozpoznać problem.

Zaryzykowałbym przypuszczenie, że jeśli nie napisałeś czegoś konkretnego na ten temat, to jest to czyjś dziennik, a może biblioteka, z której korzystasz?

Emile
źródło
1
dzięki, robię zapytania db, ale o dziwo to ostrzeżenie nie pojawia się podczas uruchamiania aplikacji na emulatorze, więc może to być spowodowane inną aplikacją zainstalowaną na moim urządzeniu.
Spojrzy
Myślę, że najnowszy logCat pokazuje Twoje wiadomości różniące się od innych aplikacji, przefiltrowane. Nie wykorzystałem go jednak wystarczająco, aby to potwierdzić. Możesz utworzyć nową pustą aplikację i obserwować log cat, aby sprawdzić, czy wystąpi błąd, co wyeliminowałoby twoją aplikację. od bycia problemem.
Emile
@frieza niekoniecznie inna aplikacja. Dodałem ArrayAdapter z sqlite i teraz otrzymuję to ostrzeżenie również na telefonie. Wydaje mi się, że nie widać żadnych błędów na emulatorze, ponieważ jest on powolny, aw konsekwencji progi wydajności są wyłączane.
alandarev
7

Miałem ten sam problem. Ostrzeżenie pojawiło się, gdy miękka klawiatura została aktywowana w jednym z moich EditTextsi aktywność straciła ostrość.

To, co zrobiłem, to schowanie klawiatury w 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();
}
antoniom
źródło
2
To jest dobra odpowiedź. Upewnij się, że ukryłeś klawiaturę, zanim wyłączysz aktywność, którą aktualnie masz na ekranie.
Gábor
1

Rozwiązałem ten problem dla siebie, być może masz ten sam problem.

Było to spowodowane przez obiekt w HeaderView z adapterem listy .

I napompowane do View i ogłoszony obiekt i umieścić TextWatcher na nim.

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

Dodano go do adaptera listy i zbudowałem adapter.

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

Wszystko jest w porządku, działa Text Watcher .

ALE jeśli kiedykolwiek odbudowałem adapter po początkowej kompilacji.

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

Ten HeaderView również jest przebudowywany.

To ostrzeżenie było wyświetlane, ponieważ obiekt został usunięty, a Obserwator tekstu nadal go obserwował.

Lista Adapter i obiektów zostały zastąpione, a ja zgadywania Tekst Watcher patrzył w drugą stronę, kiedy to się stało.

Więc ostrzeżenie znika i w cudowny sposób Text Watcher znajduje HeaderView i Object . Ale traci koncentrację i rejestruje to ostrzeżenie.

Za pomocą

JOBSadapter.notifyDataSetChanged();

naprawiono problem.

ALE jeśli masz obiekt wewnątrz adaptera , a Text Watcher jest dołączony do obiektu wewnątrz adaptera . Wtedy możesz potrzebować trochę więcej pracy.

Spróbuj usunąć Listener i dołączyć go ponownie po wykonaniu jakiejkolwiek pracy, którą wykonujesz.

Object.removeTextChangedListener();

lub

Object.addTextChangedListener(null);
Xjasz
źródło
1

Oprócz odpowiedzi antonioma upewnij się, że wszelkie dalsze czynności, które trzeba wykonać, są naprawdę wykonywane po ukryciu klawiatury, więc jeśli ukryłeś klawiaturę jak poniżej:

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

, po ukryciu klawiatury musisz wykonać kolejne akcje, na przykład:

getWindow().getDecorView().post(new Runnable() {            
        @Override
        public void run() {
            finish(); //Sample succeeding code
     }
});
Pier Betos
źródło
0

Miałem ten problem, gdy musiałem zmodyfikować lub pobrać tekst z EditText i był on skupiony.

Więc przed modyfikacją lub uzyskaniem z niego zamknąłem klawiaturę i naprawiłem.

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

Może twój problem jest inny.

Angelo Moroni
źródło
0

Rozwiązałem swój problem podczas wstawiania typu wejściowego do XML w następujący sposób: android: inputType = "none | text | textCapWords | textUri"

wcześniej był to android: inputType = "text" To rozwiązało mój problem.

Neemias Fernandes
źródło
3
Nic dla mnie nie zrobił.
DSlomer64
0

Błąd w Logcat: getTextBeforeCursor przy nieaktywnym InputConnection

Rozwiązanie: Ukryj klawiaturę wejściową i uruchom aplikację.

nieśmiały
źródło
0

Ukryj klawiaturę programową przed wyczyszczeniem EditText - ostrzeżenia nie będą wyświetlane.

Wydaje się również, że jest to specyficzne dla urządzenia . Widziałem to tylko na Nexusie 4 (Android 7.1). Brak ostrzeżeń na emulatorach (8.0, 7.1) lub Nexus 5.

Inoy
źródło
0

Mój problem był spowodowany ustawieniem widoczności EditTextdo, GONEa następnie natychmiastowym ustawieniem go za VISIBLEkażdym razem, gdy użytkownik wpisał znak, ponieważ przeprowadzałem walidację na wejściu za każdym razem, gdy tekst się zmieniał, aw niektórych przypadkach widok musiał być ukryty.

Dlatego rozwiązaniem jest unikanie ustawiania widoczności widoku lub układu na GONE między aktualizacjami interfejsu użytkownika lub stanu, ponieważ EditTextmoże to spowodować utratę aktywności

TheIT
źródło
0

iface ten sam problem i napraw go, konwertując mój widget bezstanowy na widget statefull, możesz go wypróbować

Mohamed Adly
źródło