getExtractedText bei inaktiver InputConnection-Warnung auf Android

127

Ich erhalte die folgende Warnung in meinem Logcat.

getExtractedText on inactive InputConnection

Ich kann den Grund dafür nicht finden. Bitte helfen Sie

pankajagarwal
quelle
4
Ich verstehe nicht, was in dieser Frage mehrdeutig / vage / unvollständig ist. Ich erhalte diese Warnung in meinem Logcat, während ich meine App ausführe. Ich möchte den Grund für diese Warnung wissen.
Pankajagarwal
2
Ich sehe dies auch in meiner Anwendung, die ich entwickle, und ich habe keine Ahnung, woher es kommt oder warum. Wenn jemand es jemals herausfindet, schreibe bitte einen Kommentar. Es werden tatsächlich viele andere Warnungen als "getExtractedText" angezeigt. Ich sehe auch: "beginBatchEdit", "endBatchEdit", "getTextBeforeCursor" und viele mehr.
Spanne
1
Schauen sich die Moderatoren diese Frage an? Wenn nicht, sollten sie es tun, denn wenn sie diese Frage auch nach 14 Gegenstimmen noch als vage und amibiguös betrachten, weiß ich nicht, was ich sagen soll
pankajagarwal
Ich stimme zu, dies ist ein Problem, das ich auch ansprechen muss. Ich habe keine Ahnung von der Ursache.
JonWillis
3
Welcher Code verursacht diesen Fehler?
Bill the Lizard

Antworten:

44

Ich bin auf ein ähnliches Problem gestoßen. Mein 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.

Meine Situation: Ich habe eine EditText-Ansicht, in die der Benutzer eingibt. Der EditText wird gelöscht, wenn der Benutzer eine Taste drückt. Viele inaktive InputConnection-Einträge werden ausgeblendet, wenn ich schnell die Taste drücke.

Ex:

editText.setText(null);

Die letzte Zeile in meinem Logcat oben gibt einen guten Hinweis darauf, was passiert. Sicher genug, die InputConnection wird von Anfragen zum Löschen des Textes überfordert. Ich habe versucht, den Code zu ändern, um die Textlänge zu überprüfen, bevor ich versucht habe, ihn zu löschen:

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

Dies hilft, das Problem zu mindern, da durch schnelles Drücken der Taste nicht mehr IInputConnectionWrapper-Warnungen ausgegeben werden. Dies ist jedoch immer noch anfällig für Probleme, wenn der Benutzer schnell zwischen dem Eingeben von etwas und dem Drücken der Taste wechselt oder die Taste drückt, wenn die App ausreichend geladen ist usw.

Glücklicherweise habe ich einen anderen Weg gefunden, um Text zu löschen: Editable.clear () . Damit bekomme ich überhaupt keine Warnungen:

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

Beachten Sie, dass Sie TextKeyListener.clear (Editable e) verwenden können, wenn Sie den gesamten Eingabestatus und nicht nur den Text (Autotext, Autocap, Multitap, Undo) löschen möchten .

if (editText.length() > 0) {
    TextKeyListener.clear(editText.getText());
}
Johnson Wong
quelle
1
Ich bekam auch IInputConnectionWrapper-Warnungen und meine App bekam fast ANR, Methode clear () funktionierte für mich ... super seltsamer Fehler, bevor ich setText ("") setzte;
Box
17

Aktualisieren:

Der Grund, warum ich InputConnection-Warnungen erhielt, war nicht, wo ich den Text eingestellt habe (dh im onTextChangedRückruf oder im afterTextChanged), sondern weil ich ihn verwendet habesetText .

Ich habe das Problem umgangen, indem ich angerufen habe:

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

Hinweis: Ich rufe immer noch im afterTextChangedRückruf an, obwohl dies auch ohne Warnungen von funktioniert ontextChanged.

Vorherige Antwort:

Ich habe auch in logcat identische Nachrichten erhalten, obwohl mein Szenario etwas anders war. Ich wollte jedes Zeichen lesen, das in EditText eingegangen ist (oder zusammengesetzte Zeichen / eingefügten Text), und dann den fraglichen EditText auf eine Standardinitialisierungszeichenfolge zurücksetzen.

Der Klartextteil funktioniert gemäß der obigen Lösung von Johnson. Das Zurücksetzen des Textes war jedoch problematisch, und ich erhielt Warnungen zur Eingabeverbindung.

Anfangs wurde mein onTextChanged(CharSequence s, ...)wie folgt definiert:

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

Beim onTextChanged(...)Aufruf befindet sich der EditText im schreibgeschützten Modus. Ich bin mir nicht sicher, ob dies bedeutet, dass wir nicht mehr tun können, als es anzurufen getText.clear()(setText(...) Aufrufe erzeugen auch inputConnection-Warnungen).

Der Rückruf afterTextChanged(Editable s)ist jedoch der richtige Ort, um den Text festzulegen.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

Dies funktioniert bisher ohne Warnungen.

ahash
quelle
Ich hatte auch das gleiche Problem. Mir wurde klar, dass Ihre Lösung zwar die InputConnection-Warnungen verschwinden lässt, ich jedoch festgestellt habe, dass die afterTextChangedMethode sowohl aufgerufen hiddenKeyboardText.getText().clear();als auch aktiviert ist hiddenKeyboardText.append("some string");, und dass diese Tatsache ebenfalls berücksichtigt werden sollte. +1 von mir!
Nick
@ Nick wahr - wichtig, um sicherzustellen, if (isResettingKeyboard) return;ist an der Spitze ...
Ahash
7

Aus den Hilfedokumenten

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

Die InputConnection-Schnittstelle ist der Kommunikationskanal von einer InputMethod zurück zu der Anwendung, die ihre Eingabe empfängt. Es wird verwendet, um beispielsweise Text um den Cursor herum zu lesen, Text in das Textfeld zu schreiben und Rohschlüsselereignisse an die Anwendung zu senden.

Darüber hinaus zeigt weiterführende Literatur

getExtractedText (): Diese Methode schlägt möglicherweise fehl, wenn die Eingabeverbindung ungültig geworden ist (z. B. wenn der Prozess abstürzt) oder der Client zu lange braucht, um mit dem Text zu antworten (es dauert einige Sekunden, bis er zurückkehrt) . In beiden Fällen wird eine Null zurückgegeben.

Es scheint auch Änderungen an diesem Text zu überwachen und Änderungen zu alarmieren.

Um das Problem zu beheben, müssen Sie alle Datenbankabfragen untersuchen, die Sie durchführen, z. B. Listenlistenansichten oder Listen in einem Layout.

Wenn Sie keine Ansichten haben, zum Beispiel, dass dies zufällig im Hintergrund geschieht, würde ich vorschlagen, dass es sich nicht um ein Problem mit UI-Elementen handelt. Ignorieren Sie also Textfelder und dergleichen. Dies kann ein Hintergrunddienst sein, der Informationen in einem Cursor speichert oder einen Cursor anfordert.

Tritt das Problem auch bei Ihrer App auf? oder vielleicht jemand anderes, den Sie kürzlich installiert haben. Listen Sie den vollständigen logCat-Trace auf. Jemand könnte das Problem erkennen.

Ich würde eine Vermutung riskieren, dass, wenn Sie nicht etwas Spezielles darüber geschrieben haben, es sich um eine andere Protokollnachricht handelt, oder vielleicht um die einer Bibliothek, die Sie verwenden?

Emile
quelle
1
danke, ich mache db-Abfragen, aber seltsamerweise wird diese Warnung nicht angezeigt, wenn die App auf dem Emulator ausgeführt wird, sodass sie möglicherweise auf eine andere auf meinem Gerät installierte App zurückzuführen ist. Werde in diese Richtung schauen
Pankajagarwal
Ich denke, die neueste logCat zeigt Ihnen Ihre Nachrichten, die sich von anderen Apps unterscheiden, gefiltert. Ich habe es jedoch nicht ausreichend verwendet, um dies zu bestätigen. Sie können eine neue leere App erstellen und die Protokollkatze beobachten, um festzustellen, ob der Fehler auftritt, der Ihre App eliminieren würde. von der Ausgabe zu sein.
Emile
@frieza nicht unbedingt andere App. Ich habe ArrayAdapter mit SQLite hinzugefügt und erhalte diese Warnung jetzt auch telefonisch. Ich denke, Sie sehen keine Fehler auf dem Emulator, weil er langsam ist und die Leistungsschwellen in der Folge deaktiviert werden.
Alandarev
7

Ich hatte das gleiche Problem. Die Warnung wurde angezeigt, als die Softtastatur in einer meiner Funktionen aktiviert wurde EditTextsund die Aktivität den Fokus verlor.

Ich habe die Tastatur in onPause () ausgeblendet.

@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();
}
Antonym
quelle
2
Dies ist die Antwort in Ordnung. Stellen Sie sicher, dass Sie die Tastatur ausblenden, bevor Sie von der Aktivität auf dem Bildschirm abweichen.
Gábor
1

Dieses Problem wurde für mich gelöst. Vielleicht haben Sie das gleiche Problem.

Dies wurde durch ein verursachtes Objekt in der HeaderView der Liste Adapter .

Ich habe eine Ansicht aufgeblasen und das Objekt deklariert und einen TextWatcher darauf platziert.

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

Fügte es dem Listenadapter hinzu und baute den Adapter.

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

Alles ist in Ordnung, der Text Watcher funktioniert.

ABER wenn ich den Adapter nach dem ersten Build jemals neu aufgebaut habe.

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

Diese HeaderView wird ebenfalls neu erstellt.

Diese Warnung würde angezeigt, weil das Objekt entfernt wurde und der Text Watcher immer noch darauf eingestellt war, darauf zu achten.

Der Listenadapter und das Objekt wurden ersetzt, und ich vermute, der Text Watcher hat in die andere Richtung geschaut, als es passierte.

Die Warnung geht also aus und der Text Watcher findet auf wundersame Weise die HeaderView und das Objekt . Aber es verliert den Fokus und protokolliert diese Warnung.

Verwenden von

JOBSadapter.notifyDataSetChanged();

Das Problem wurde behoben.

ABER wenn Sie ein Objekt im Adapter haben und der Text Watcher an das Objekt im Adapter angehängt ist . Dann müssen Sie möglicherweise etwas mehr arbeiten.

Entfernen Sie den Listener und hängen Sie ihn erneut an, nachdem Sie die von Ihnen ausgeführten Arbeiten ausgeführt haben.

Object.removeTextChangedListener();

oder

Object.addTextChangedListener(null);
Xjasz
quelle
1

Stellen Sie neben der Antwort von antoniom sicher, dass alle weiteren Aktionen, die ausgeführt werden müssen, wirklich ausgeführt werden, nachdem Sie die Tastatur ausgeblendet haben. Wenn Sie also die Tastatur wie die folgende ausgeblendet haben:

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

Nach dem Ausblenden der Tastatur müssen nachfolgende Aktionen ausgeführt werden:

getWindow().getDecorView().post(new Runnable() {            
        @Override
        public void run() {
            finish(); //Sample succeeding code
     }
});
Pier Betos
quelle
0

Ich hatte dieses Problem, als ich Text von EditText ändern oder abrufen musste, und er war fokussiert.

Bevor ich etwas ändere oder davon bekomme, habe ich die Tastatur geschlossen und es repariert.

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

Vielleicht ist Ihr Problem anders.

Angelo Moroni
quelle
0

Ich hatte mein Problem beim Einfügen eines Eingabetyps in XML wie folgt gelöst: android: inputType = "none | text | textCapWords | textUri"

vorher war android: inputType = "text" Dies löste mein Problem.

Neemias Fernandes
quelle
3
Hab nichts für mich getan.
DSlomer64
0

Fehler in Logcat: getTextBeforeCursor bei inaktiver InputConnection

Lösung: Blenden Sie Ihre Eingabetastatur aus und führen Sie die Anwendung aus.

Shyam
quelle
0

Blenden Sie die Softwaretastatur aus, bevor Sie EditText löschen. Warnungen werden nicht angezeigt.

Es scheint auch gerätespezifisch zu sein . Ich habe es nur auf Nexus 4 (Android 7.1) gesehen. Keine Warnungen auf Emulatoren (8.0, 7.1) oder Nexus 5.

Inoy
quelle
0

Mein Problem wurde dadurch verursacht, dass die Sichtbarkeit von EditTextto GONEund dann sofort auf VISIBLEjedes Mal eingestellt wurde, wenn der Benutzer ein Zeichen eingab, da ich die Eingabe jedes Mal überprüfte, wenn sich der Text änderte und in einigen Fällen die Ansicht ausgeblendet werden musste.

Die Lösung besteht daher darin, zu vermeiden, dass die Sichtbarkeit der Ansicht oder des Layouts zwischen Benutzeroberflächen- oder Statusaktualisierungen auf GONE gesetzt wird, da dies den EditTextFokus verlieren kann

Das es
quelle
0

Wenn Sie das gleiche Problem beheben und es beheben, indem Sie mein zustandsloses Widget in ein Statefull-Widget konvertieren, können Sie es versuchen

Mohamed Adly
quelle