getExtracedText sur l'avertissement InputConnection inactif sur Android


128

J'obtiens l'avertissement suivant dans mon logcat.

getExtractedText on inactive InputConnection

Je suis incapable de trouver la raison derrière cela. Veuillez aider


4
Je ne comprends pas ce qui est ambigu / vague / incomplet dans cette question? J'obtiens cet avertissement dans mon logcat lors de l'exécution de mon application, je veux connaître la raison de cet avertissement.
pankajagarwal

2
Je le vois également dans mon application que je développe et je n'ai aucune idée d'où cela vient ni pourquoi. Si quelqu'un le découvre, veuillez poster un commentaire. Il affiche en fait de nombreux avertissements différents autres que "getExtrectedText". Je vois aussi: "beginBatchEdit", "endBatchEdit", "getTextBeforeCursor" et bien d'autres.
span

1
les modérateurs se penchent-ils sur cette question. Sinon, ils devraient parce que s'ils croient toujours que cette question est vague et ambiguë même après 14 votes positifs, je ne sais pas quoi dire
pankajagarwal

Je suis d'accord, c'est un problème que je dois également résoudre. Je n'ai aucune idée de la cause.
JonWillis

3
Quel code avez-vous qui cause cette erreur?
Bill the Lizard

Réponses:


44

J'ai rencontré un problème similaire. Mon 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.

Ma situation: j'ai une vue EditText dans laquelle l'utilisateur tape. Le EditText est effacé lorsque l'utilisateur appuie sur un bouton. De nombreuses entrées InputConnection inactives sont diffusées lorsque j'appuie rapidement sur le bouton.

Ex:

editText.setText(null);

La dernière ligne de mon logcat ci-dessus fournit une excellente indication de ce qui se passe. Effectivement, InputConnection est submergé par les demandes d'effacement du texte. J'ai essayé de modifier le code pour vérifier la longueur du texte avant d'essayer de l'effacer:

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

Cela permet d'atténuer le problème en ce que le fait d'appuyer rapidement sur le bouton ne provoque plus le flux d'avertissements IInputConnectionWrapper. Cependant, cela pose toujours des problèmes lorsque l'utilisateur alterne rapidement entre taper quelque chose et appuyer sur le bouton ou appuie sur le bouton lorsque l'application est sous une charge suffisante, etc.

Heureusement, j'ai trouvé un autre moyen d'effacer le texte: Editable.clear () . Avec cela, je ne reçois pas du tout d'avertissement:

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

Notez que si vous souhaitez effacer tout l'état d'entrée et pas seulement le texte (autotext, autocap, multitap, undo), vous pouvez utiliser TextKeyListener.clear (Editable e) .

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

1
Je recevais également des avertissements IInputConnectionWrapper et mon application avait presque ANR, la méthode clear () fonctionnait pour moi ... bogue super étrange, avant de définir setText ("");
boîte du

17

Mettre à jour:

La raison pour laquelle je recevais des avertissements InputConnection n'était pas à cause de l'endroit où je définissais le texte (c'est-à-dire dans le onTextChangedrappel ou le afterTextChanged) - c'était parce que j'utilisais setText.

J'ai contourné le problème en appelant:

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

Remarque: je passe toujours l'appel dans le afterTextChangedrappel, même si cela fonctionne sans avertissements deontextChanged .

Réponse précédente:

J'obtenais également des messages identiques dans logcat, même si mon scénario était légèrement différent. Je voulais lire tous les caractères qui entraient dans EditText (ou caractères composés / texte collé), puis réinitialiser le EditText en question à une chaîne d'initialisation par défaut.

La partie en texte clair fonctionne selon la solution de Johnson ci-dessus. Cependant, la réinitialisation du texte était problématique et j'obtenais des avertissements de connexion d'entrée.

Initialement, mon onTextChanged(CharSequence s, ...)était défini comme suit:

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

Lorsqu'il onTextChanged(...)est appelé, le EditText est en mode lecture seule. Je ne suis pas sûr que cela signifie que nous ne pouvons pas faire plus que de l'appeler getText.clear()(les setText(...)appels produisent également des avertissements inputConnection).

Cependant, le rappel afterTextChanged(Editable s)est le bon endroit pour définir le texte.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

Cela fonctionne jusqu'à présent sans aucun avertissement.


J'ai eu le même problème aussi. Ce que j'ai réalisé, c'est que bien que votre solution fasse disparaître les avertissements InputConnection, j'ai remarqué que la afterTextChangedméthode est appelée hiddenKeyboardText.getText().clear();aussi bien que sur hiddenKeyboardText.append("some string");, et ce fait doit également être pris en compte. +1 de moi!
Nick

@Nick true - important de s'assurer qu'il if (isResettingKeyboard) return;est au top ...
ahash

7

À partir des documents d'aide

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

L'interface InputConnection est le canal de communication entre un InputMethod et l'application qui reçoit son entrée. Il est utilisé pour effectuer des opérations telles que la lecture de texte autour du curseur, la validation de texte dans la zone de texte et l'envoi d'événements clés bruts à l'application.

En outre, d'autres lectures montrent

getExtrectedText (): Cette méthode peut échouer si la connexion d'entrée est devenue invalide (comme le blocage de son processus) ou si le client met trop de temps à répondre avec le texte (il lui reste quelques secondes pour revenir) . Dans les deux cas, un null est renvoyé.

Il semble également surveiller les modifications apportées à ce texte et alerter les modifications.

Pour rechercher le problème, vous devrez explorer toutes les requêtes de base de données que vous effectuez, peut-être autour de listViews ou de listes dans une mise en page.

Si vous n'avez aucune vue, par exemple, cela se passe au hasard en arrière-plan, alors je suggérerais que ce n'est pas un problème d'élément d'interface utilisateur, alors ignorez les champs de texte et autres. Il peut s'agir d'un service d'arrière-plan qui stocke des informations dans un curseur ou qui demande un curseur.

De plus, le problème provient-il de votre application? ou peut-être quelqu'un d'autre que vous avez installé récemment. Répertoriez la trace logCat complète. Quelqu'un pourrait reconnaître le problème.

Je risquerais de penser que si vous n'avez pas écrit quelque chose de spécifique autour de cela, c'est quelqu'un d'autre dans le journal du message, ou peut-être celui d'une bibliothèque que vous utilisez?


1
merci, je fais des requêtes db mais étrangement, cet avertissement ne s'affiche pas lors de l'exécution de l'application sur l'émulateur, donc cela peut être dû à une autre application installée sur mon appareil. Regardera dans cette direction
pankajagarwal

Je pense que le dernier logCat vous montre vos messages distincts des autres applications, filtrés. Je ne l'ai pas suffisamment utilisé pour le confirmer. Vous pouvez créer une nouvelle application vide et regarder le chat du journal pour voir si l'erreur se produit, ce qui éliminerait votre application. d'être le problème.
Emile

@frieza pas nécessairement une autre application. J'ai ajouté ArrayAdapter avec sqlite et je reçois également cet avertissement sur le téléphone. Je suppose que vous ne voyez aucune erreur sur l'émulateur, car il est lent et les seuils de performance sont désactivés en conséquence.
alandarev

7

J'avais le même problème. L'avertissement est apparu lorsque le clavier virtuel a été activé dans l'un de mesEditTexts et que l'activité perd sa concentration.

Ce que j'ai fait, c'est de cacher le clavier dans 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
C'est la bonne réponse. Assurez-vous de masquer le clavier avant de quitter l'activité que vous avez actuellement à l'écran.
Gábor

1

J'ai résolu ce problème pour moi, peut-être que vous avez le même problème.

Cela était dû à un objet dans le HeaderView de l' adaptateur de liste .

J'ai gonflé une vue et déclaré l' objet et mis un TextWatcher dessus.

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

Ajouté à l' adaptateur de liste et construit l'adaptateur.

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

Tout va bien, le Text Watcher fonctionne.

MAIS si jamais je reconstruis l'adaptateur après la construction initiale.

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

Cette HeaderView est également reconstruit.

Cet avertissement s'afficherait car l' objet a été supprimé et l'observateur de texte était toujours configuré pour le surveiller.

L' adaptateur de liste et l' objet ont été remplacés, et je suppose que l'Observateur de texte regardait dans l'autre sens quand cela s'est produit.

Ainsi, l'avertissement se déclenche et, miraculeusement, le Text Watcher trouve le HeaderView et l' objet . Mais il perd le focus et enregistre cet avertissement.

En utilisant

JOBSadapter.notifyDataSetChanged();

résolu le problème.

MAIS si vous avez un objet à l'intérieur de l' adaptateur et que l' observateur de texte est attaché à l' objet à l'intérieur de l' adaptateur . Ensuite, vous devrez peut-être faire un peu plus de travail.

Essayez de supprimer l'auditeur et de le rattacher après avoir effectué le travail que vous pourriez faire.

Object.removeTextChangedListener();

ou

Object.addTextChangedListener(null);

1

En plus de la réponse d'Antoniom, assurez-vous que toutes les actions supplémentaires nécessaires sont réellement effectuées après avoir caché le clavier, donc si vous avez masqué le clavier comme celui ci-dessous:

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

, vous devez avoir des actions réussies après le masquage du clavier, comme ceci:

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

0

J'ai eu ce problème lorsque je devais modifier ou obtenir du texte à partir de EditText et il était concentré.

Alors avant de le modifier ou d'en obtenir, j'ai fermé le clavier et je le répare.

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

Peut-être que votre problème est différent.


0

J'avais résolu mon problème en insérant un type d'entrée sur xml comme ceci: android: inputType = "none | text | textCapWords | textUri"

avant c'était android: inputType = "text" Cela a résolu mon problème.


3
Je n'ai rien fait pour moi.
DSlomer64

0

Erreur dans Logcat: getTextBeforeCursor sur InputConnection inactive

Solution: cachez votre clavier de saisie et exécutez l'application.


0

Masquer le clavier logiciel avant d'effacer EditText - les avertissements ne seront pas affichés.

En outre, cela semble être spécifique à l' appareil . Je ne l'ai vu que sur Nexus 4 (Android 7.1). Aucun avertissement sur les émulateurs (8.0, 7.1) ou Nexus 5.


0

Mon problème a été causé par la définition de la visibilité du EditTextà GONE, puis la définition immédiateVISIBLE chaque fois que l'utilisateur tapait un caractère, car j'exécutais la validation sur l'entrée chaque fois que le texte était modifié et dans certains cas, la vue devait être masquée.

La solution est donc d'éviter la mise en visibilité de la vue ou la mise en page pour GONE entre l' interface utilisateur ou des mises à jour d'état, comme EditTextpeut perdre le focus


0

Si vous rencontrez le même problème et corrigez-le en convertissant mon widget sans état en widget avec état, vous pouvez l'essayer

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.