getExtractedText su avviso InputConnection inattivo su Android


128

Ricevo il seguente avviso nel mio logcat.

getExtractedText on inactive InputConnection

Non riesco a trovare il motivo dietro. Per favore aiuto


4
Non capisco cosa sia ambiguo / vago / incompleto in questa domanda? Ricevo questo avviso nel mio logcat mentre eseguo la mia app, voglio sapere il motivo di questo avviso.
pankajagarwal,

2
Lo vedo anche nella mia applicazione che sto sviluppando e non ho idea da dove provenga o perché. Se qualcuno lo scopre, si prega di pubblicare un commento. In realtà mostra molti avvertimenti diversi da "getExtractedText". Vedo anche: "beginBatchEdit", "endBatchEdit", "getTextBeforeCursor" e molti altri.
trascorso il

1
sono i moderatori che danno un'occhiata a questa domanda. Altrimenti dovrebbero farlo perché se ancora credono che questa domanda sia vaga e ambigua anche dopo 14 voti, non so cosa dire
pankajagarwal

Concordo, anche questo è un problema che devo affrontare. Non ho idea della causa.
JonWillis,

3
Quale codice hai che sta causando questo errore?
Bill the Lizard,

Risposte:


44

Ho riscontrato un problema simile. Il mio 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.

La mia situazione: ho un EditText in cui l'utente digita. EditText viene cancellato quando l'utente preme un pulsante. Molte voci inattive di InputConnection escono in streaming quando premo rapidamente il pulsante.

Ex:

editText.setText(null);

L'ultima riga nel mio logcat sopra fornisce una grande indicazione di ciò che sta accadendo. Abbastanza sicuro, InputConnection è sopraffatto dalle richieste di cancellare il testo. Ho provato a modificare il codice per verificare la lunghezza del testo prima di provare a cancellarlo:

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

Questo aiuta a mitigare il problema in quanto la pressione rapida del pulsante non causa più il flusso di avvisi IInputConnectionWrapper. Tuttavia, questo è ancora soggetto a problemi quando l'utente si alterna rapidamente tra la digitazione di qualcosa e la pressione del pulsante o preme il pulsante quando l'app è sotto carico sufficiente, ecc.

Fortunatamente, ho trovato un altro modo per cancellare il testo: Editable.clear () . Con questo non ricevo affatto avvisi:

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

Si noti che se si desidera cancellare tutto lo stato di input e non solo il testo (autotext, autocap, multitap, annulla), è possibile utilizzare TextKeyListener.clear (modificabile e) .

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

1
Stavo ricevendo anche avvisi IInputConnectionWrapper e la mia app ha ottenuto quasi ANR, il metodo clear () ha funzionato per me ... un bug super strano, prima di impostare setText ("");
scatola

17

Aggiornare:

Il motivo per cui stavo ricevendo gli avvisi InputConnection non era a causa di dove stavo impostando il testo (cioè, nel onTextChangedcallback o il afterTextChanged) - era perché stavo usando setText.

Ho risolto il problema chiamando:

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

Nota: continuo a effettuare la chiamata nel afterTextChangedcallback, sebbene funzioni anche senza avvisi ontextChanged.

Risposta precedente:

Stavo ricevendo messaggi identici anche in logcat, sebbene il mio scenario fosse leggermente diverso. Volevo leggere ogni carattere che entrava in EditText (o composto da caratteri / testo incollato), quindi reimpostare EditText in questione su una stringa di inizializzazione predefinita.

La parte in testo chiaro funziona secondo la soluzione di Johnson sopra. Tuttavia, il ripristino del testo era problematico e avrei ricevuto avvisi di inputconnection.

Inizialmente, il mio onTextChanged(CharSequence s, ...)era definito come segue:

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

Quando onTextChanged(...)viene chiamato, EditText è in sola lettura. Non sono sicuro che ciò significhi che non possiamo fare altro che chiamarlo getText.clear()(le setText(...)chiamate producono anche avvisi inputConnection).

Tuttavia, il callback afterTextChanged(Editable s)è il posto giusto per impostare il testo.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

Questo, finora, funziona senza alcun avvertimento.


Ho avuto anche lo stesso problema. Quello che ho capito è che, sebbene la tua soluzione faccia scomparire gli avvisi di InputConnection, ho notato che il afterTextChangedmetodo viene chiamato hiddenKeyboardText.getText().clear();oltre che attivo hiddenKeyboardText.append("some string");e questo fatto dovrebbe essere preso in considerazione. +1 da me!
Nick,

@Nick true - importante assicurarsi che if (isResettingKeyboard) return;sia in cima ...
ahash

7

Dai documenti di aiuto

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

L'interfaccia InputConnection è il canale di comunicazione da un InputMethod all'applicazione che sta ricevendo il suo input. Viene utilizzato per eseguire operazioni quali la lettura di testo attorno al cursore, il commit del testo nella casella di testo e l'invio di eventi chiave non elaborati all'applicazione.

Inoltre, ulteriori letture mostrano

getExtractedText (): questo metodo potrebbe non riuscire se la connessione di input è diventata non valida (come l'arresto anomalo del processo) o se il client impiega troppo tempo a rispondere con il testo (vengono restituiti un paio di secondi per tornare) . In entrambi i casi, viene restituito un valore nullo.

Sembra anche monitorare le modifiche a tale testo e avvisare le modifiche.

Per risolvere il problema dovrai esplorare tutte le query del database che stai effettuando, magari attorno a listView o elenchi in un layout.

Se non hai alcuna vista, ad esempio sta accadendo in modo casuale in background, quindi suggerirei che non è un problema di elemento dell'interfaccia utente, quindi ignora i campi di testo e così via. Potrebbe essere un servizio in background che memorizza informazioni in un cursore o richiede un cursore.

Inoltre, il problema sorge dalla tua app? o forse qualcun altro che hai installato di recente. Elencare la traccia logCat completa. Qualcuno potrebbe riconoscere il problema.

Immagino che se non hai scritto qualcosa di specifico in questo che il suo qualcuno elogia il messaggio di log, o forse quello di una libreria che stai usando?


1
grazie, faccio query db ma stranamente questo avviso non viene visualizzato quando eseguo l'app sull'emulatore, quindi potrebbe effettivamente essere dovuto a qualche altra app installata sul mio dispositivo.
Guarderà

Penso che l'ultimo logCat ti mostri i tuoi messaggi distinti da altre app, filtrati. Non l'ho usato abbastanza per confermarlo però. È possibile creare una nuova app vuota e guardare il gatto di registro per vedere se si verifica l'errore che eliminerebbe l'app. di essere il problema.
Emile,

@frieza non necessariamente altra app. Ho aggiunto ArrayAdapter con sqlite e ora sto ricevendo anche questo avviso sul telefono. Suppongo che non vedi errori sull'emulatore perché è lento e le soglie delle prestazioni sono state disabilitate di conseguenza.
alandarev,

7

Avevo lo stesso problema. L'avvertimento è apparso quando la tastiera virtuale è stata attivata in una delle mie EditTextse l'attività non è più attiva .

Quello che ho fatto è stato nascondere la tastiera in 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
Questa è la risposta, va bene. Assicurati di nascondere la tastiera prima di abbandonare l'attività che hai attualmente sullo schermo.
Gábor,

1

Risolto questo problema per me stesso forse hai lo stesso problema.

Ciò è stato causato da un oggetto nel HeaderView della Adapter List .

Ho gonfiato una vista e dichiarato l' oggetto e messo un TextWatcher su di esso.

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

Aggiunto all'Adattatore elenco e creato l'adattatore.

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

Va tutto bene il Text Watcher funziona.

MA se ho mai ricostruito l'adattatore dopo la build iniziale.

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

Anche HeaderView è stato ricostruito.

Quell'avvertimento sarebbe mostrato perché l' Oggetto era stato rimosso e Text Watcher era ancora impostato a cercarlo.

L' adattatore elenco e l' oggetto sono stati sostituiti, e immagino che Text Watcher guardasse dall'altra parte quando è successo.

Quindi l'avviso si spegne e miracolosamente Text Watcher trova HeaderView e Object . Ma perde attenzione e registra quell'avvertimento.

utilizzando

JOBSadapter.notifyDataSetChanged();

risolto il problema.

MA se hai un oggetto all'interno dell'adattatore e Text Watcher è collegato all'oggetto all'interno dell'adattatore . Quindi potrebbe essere necessario fare un po 'più di lavoro.

Prova a rimuovere Listener e ricollegalo dopo aver fatto qualsiasi lavoro tu stia facendo.

Object.removeTextChangedListener();

o

Object.addTextChangedListener(null);

1

A parte la risposta di Antoniom, assicurati che tutte le altre azioni che devono essere fatte, siano davvero fatte dopo aver nascosto la tastiera, quindi se hai nascosto la tastiera come quella qui sotto:

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

, devi eseguire le azioni successive dopo aver nascosto la tastiera, in questo modo:

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

0

Ho avuto questo problema quando ho dovuto modificare o ottenere testo da EditText ed era focalizzato.

Quindi, prima di modificarlo o ottenerlo, ho chiuso la tastiera e l'ho risolto.

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

Forse, il tuo problema è diverso.


0

Avevo risolto il mio problema inserendo un tipo di input su xml in questo modo: android: inputType = "none | text | textCapWords | textUri"

prima era android: inputType = "text" Questo ha risolto il mio problema.


3
Non ha fatto niente per me.
DSlomer64,

0

Errore in Logcat: getTextBeforeCursor su InputConnection inattivo

Soluzione: nascondi la tastiera di input ed esegui l'applicazione.


0

Nascondi la tastiera del software prima di cancellare EditText - gli avvisi non verranno visualizzati.

Inoltre, sembra essere specifico del dispositivo . L'ho visto solo su Nexus 4 (Android 7.1). Nessun avviso sugli emulatori (8.0, 7.1) o Nexus 5.


0

Il mio problema è stato causato impostando la visibilità di EditTexta GONEe quindi impostandola immediatamente VISIBLEogni volta che l'utente digitava un carattere, poiché stavo eseguendo la convalida sull'input ogni volta che il testo cambiava e in alcuni casi la vista doveva essere nascosta.

La soluzione è quindi quella di evitare di impostare la visibilità della vista o del layout su GONE tra l'interfaccia utente o gli aggiornamenti di stato, in quanto ciò EditTextpotrebbe perdere la concentrazione


0

iface lo stesso problema e risolvilo convertendo il mio widget senza stato in widget con stato puoi provarlo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.