getExtractedText en advertencia de InputConnection inactiva en Android

128

Recibo la siguiente advertencia en mi logcat.

getExtractedText on inactive InputConnection

No puedo encontrar la razón detrás de esto. Por favor ayuda

pankajagarwal
fuente
44
No entiendo lo que es ambiguo / vago / incompleto en esta pregunta. Recibo esta advertencia en mi logcat mientras ejecuto mi aplicación, quiero saber el motivo de esta advertencia.
pankajagarwal
2
También estoy viendo esto en mi aplicación que estoy desarrollando y no tengo idea de dónde viene ni por qué. Si alguien se entera, por favor publique un comentario. En realidad, muestra muchas advertencias diferentes además de "getExtractedText". También veo: "beginBatchEdit", "endBatchEdit", "getTextBeforeCursor" y muchos más.
abarca
1
son los moderadores echando un vistazo a esta pregunta. Si no, entonces deberían hacerlo, porque si todavía creen que esta pregunta es vaga y ambigua incluso después de 14 votos a favor, entonces no sé qué decir
pankajagarwal
Estoy de acuerdo, este es un problema que también necesito abordar. No tengo idea de la causa.
JonWillis
3
¿Qué código tienes que está causando este error?
Bill the Lizard

Respuestas:

44

Me encontré con un problema similar. Mi 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.

Mi situación: tengo una vista EditText en la que el usuario escribe. EditText se borra cuando el usuario presiona un botón. Muchas entradas inactivas de InputConnection salen cuando presiono rápidamente el botón.

Ex:

editText.setText(null);

La última línea en mi logcat anterior proporciona una gran indicación de lo que está sucediendo. Efectivamente, InputConnection está abrumado por las solicitudes para borrar el texto. Intenté modificar el código para verificar la longitud del texto antes de intentar borrarlo:

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

Esto ayuda a mitigar el problema, ya que presionar el botón rápidamente ya no provoca la corriente de advertencias IInputConnectionWrapper. Sin embargo, esto sigue siendo propenso a problemas cuando el usuario alterna rápidamente entre escribir algo y presionar el botón o presionar el botón cuando la aplicación está bajo carga suficiente, etc.

Afortunadamente, encontré otra forma de borrar el texto: Editable.clear () . Con esto no recibo advertencias en absoluto:

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

Tenga en cuenta que si desea borrar todo el estado de entrada y no solo el texto (autotext, autocap, multitap, undo), puede usar TextKeyListener.clear (Editable e) .

if (editText.length() > 0) {
    TextKeyListener.clear(editText.getText());
}
Johnson Wong
fuente
1
También recibí advertencias IInputConnectionWrapper y mi aplicación obtuvo casi ANR, el método clear () funcionó para mí ... error súper extraño, antes de configurar setText ("");
cuadro
17

Actualizar:

La razón por la que recibí advertencias de InputConnection no se debió a dónde estaba configurando el texto (es decir, en la onTextChangeddevolución de llamada o al afterTextChanged), sino porque estaba usando setText.

Resolví el problema llamando a:

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

Nota: Todavía hago la llamada en la afterTextChangeddevolución de llamada, aunque también funciona sin advertencias ontextChanged.

Respuesta anterior:

También recibí mensajes idénticos en logcat, aunque mi escenario era ligeramente diferente. Quería leer cada carácter que entraba en EditText (o caracteres compuestos / texto pegado), y luego restablecer EditText en cuestión a una cadena de inicialización predeterminada.

La parte de texto claro funciona según la solución de Johnson anterior. Sin embargo, restablecer el texto fue problemático, y recibí advertencias de conexión de entrada.

Inicialmente, mi onTextChanged(CharSequence s, ...) se definió de la siguiente manera:

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

Cuando onTextChanged(...) se llama, EditText está en modo de solo lectura. No estoy seguro de si esto significa que no podemos hacer más que invocarlo getText.clear()(las setText(...)llamadas también producen advertencias de inputConnection).

Sin embargo, la devolución de llamada afterTextChanged(Editable s) es el lugar correcto para configurar el texto.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

Hasta el momento, esto funciona sin ninguna advertencia.

ahash
fuente
Yo también tuve el mismo problema. Lo que me di cuenta fue que a pesar de sus marcas solución desaparecen las advertencias InputConnection, me di cuenta de que afterTextChangedel método se llama en hiddenKeyboardText.getText().clear();y sobre hiddenKeyboardText.append("some string");, y este hecho también deben tenerse en cuenta. +1 de mi parte!
Nick
@Nick true: es importante asegurarse de que if (isResettingKeyboard) return;esté en la cima ...
ahash
7

De los documentos de ayuda

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

La interfaz InputConnection es el canal de comunicación desde un InputMethod a la aplicación que está recibiendo su entrada. Se utiliza para realizar tareas tales como leer texto alrededor del cursor, confirmar texto en el cuadro de texto y enviar eventos clave sin procesar a la aplicación.

Además, la lectura adicional muestra

getExtractedText (): este método puede fallar si la conexión de entrada se ha vuelto inválida (por ejemplo, si el proceso se bloquea) o si el cliente tarda demasiado en responder con el texto (se le devuelve un par de segundos) . En cualquier caso, se devuelve un valor nulo.

Parece que también supervisa los cambios a dicho texto y alerta los cambios.

Para buscar el problema, tendrá que explorar cualquier consulta de base de datos que esté haciendo, tal vez alrededor de listViews o listas en un diseño.

Si no tiene ninguna vista, por ejemplo, está sucediendo aleatoriamente en segundo plano, entonces sugeriría que no es un problema de elemento de la interfaz de usuario, así que ignore los campos de texto y demás. Podría ser un servicio en segundo plano que almacena información en un cursor o solicita un cursor.

Además, ¿surge el problema de su aplicación? o quizás alguien más que hayas instalado recientemente. Listar el seguimiento completo de logCat. Alguien podría reconocer el problema.

Me arriesgaría a adivinar que si no ha escrito algo específico sobre esto, ¿es alguien más el mensaje de registro, o tal vez el de una biblioteca que está usando?

Emile
fuente
1
gracias, hago consultas de db pero extrañamente esta advertencia no aparece cuando ejecuto la aplicación en el emulador, por lo que en realidad podría deberse a alguna otra aplicación instalada en mi dispositivo.
Mirará
Creo que el último logCat le muestra sus mensajes distintos de otras aplicaciones, filtrados. Sin embargo, no lo he usado lo suficiente como para confirmar eso. Puede crear una nueva aplicación vacía y ver el registro de gato para ver si se produce el error, eso eliminaría su aplicación. de ser el problema.
Emile el
@frieza no necesariamente otra aplicación. He agregado ArrayAdapter con sqlite y ahora también recibo esta advertencia por teléfono. Supongo que no ve errores en el emulador porque es lento y los umbrales de rendimiento se deshabilitan como consecuencia.
alandarev
7

Estaba teniendo el mismo problema. La advertencia apareció cuando el teclado virtual se activó en uno de mis EditTextsy la actividad perdió el foco.

Lo que hice fue ocultar el teclado en 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
fuente
2
Esta es la respuesta, de acuerdo. Asegúrese de ocultar el teclado antes de alejarse de la actividad que tiene actualmente en la pantalla.
Gábor
1

Resolví este problema por mí mismo, tal vez tengas el mismo problema.

Esto fue causado por un objeto en el HeaderView del Adaptador de lista .

Inflé una vista y declaró el objeto y le puse un 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
        }
});

Lo agregó al Adaptador de lista y creó el adaptador.

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

Todo está bien, el Text Watcher funciona.

PERO si alguna vez reconstruí el adaptador después de la compilación inicial.

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

Ese encabezado se reconstruye.

Esa advertencia se mostraría porque el Objeto se eliminó y el Observador de texto todavía estaba configurado para vigilarlo.

El Adaptador de lista y el Objeto fueron reemplazados, y supongo que el Observador de texto estaba mirando hacia otro lado cuando sucedió.

Entonces, la advertencia se dispara y milagrosamente el Text Watcher encuentra el HeaderView y el Object . Pero pierde el foco y registra esa advertencia.

Utilizando

JOBSadapter.notifyDataSetChanged();

solucionó el problema.

PERO si tiene un Objeto dentro del Adaptador , y el Observador de Texto está conectado al Objeto dentro del Adaptador . Entonces es posible que deba hacer un poco más de trabajo.

Intente eliminar el oyente y vuelva a conectarlo después de hacer cualquier trabajo que esté haciendo.

Object.removeTextChangedListener();

o

Object.addTextChangedListener(null);
Xjasz
fuente
1

Además de la respuesta de antoniom, asegúrese de que cualquier otra acción que se necesite hacer, realmente se realice después de ocultar el teclado, así que si ha ocultado el teclado como el siguiente:

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

, debe realizar acciones subsiguientes después de ocultar el teclado, así:

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

Tuve este problema cuando tuve que modificar u obtener texto de EditText y estaba enfocado.

Entonces, antes de modificarlo o obtenerlo, cerré el teclado y lo reparé.

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

Tal vez, tu problema es diferente.

Angelo Moroni
fuente
0

Había resuelto mi problema al insertar un tipo de entrada en xml como este: android: inputType = "none | text | textCapWords | textUri"

antes de eso era android: inputType = "text" Esto resolvió mi problema.

Neemias Fernandes
fuente
3
No hizo nada por mi.
DSlomer64
0

Error en Logcat: getTextBeforeCursor en InputConnection inactivo

Solución: oculte su teclado de entrada y ejecute la aplicación.

shyam
fuente
0

Ocultar el teclado del software antes de borrar EditText : no se mostrarán advertencias.

Además, parece ser específico del dispositivo . Lo he visto solo en Nexus 4 (Android 7.1). Sin advertencias en emuladores (8.0, 7.1) o Nexus 5.

Inoy
fuente
0

Mi problema fue causado por ajuste de la visibilidad de la EditTextque GONEe inmediatamente después ajustarlo a VISIBLEcada vez que el usuario ha escrito un personaje, como yo estaba corriendo la validación de la entrada cada vez que el texto ha cambiado y en algunos casos la visión necesario que se oculta.

Por lo tanto, la solución es evitar establecer la visibilidad de Vista o Diseño en GONE entre UI o actualizaciones de estado, ya que EditTextpueden perder el foco

La cosa
fuente
0

Si tiene el mismo problema y lo soluciona convirtiendo mi widget sin estado en widget con estado, puede probarlo

Mohamed Adly
fuente