getExtractedText on inactive InputConnection warning on android

I ran into a similar issue. My 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.

My situation: I have an EditText view the user types into. The EditText gets cleared when user presses a button. Lots of inactive InputConnection entries stream out when I rapidly press the button.

Ex:

editText.setText(null);

The last line in my logcat above provides a great indication of what is happening. Sure enough, the InputConnection is overwhelmed by requests to clear the text. I tried modifying the code to check for text length before trying to clear it:

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

This helps mitigate the problem in that pressing the button rapidly no longer causes the stream of IInputConnectionWrapper warnings. However this is still prone to problems when the user rapidly alternates between typing something and pressing the button or presses the button when the app is under sufficient load, etc.

Fortunately, I found another way to clear text: Editable.clear(). With this I don't get warnings at all:

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

Note that should you wish to clear all input state and not just the text (autotext, autocap, multitap, undo), you can use TextKeyListener.clear(Editable e).

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

Update:

The reason I was getting InputConnection warnings was not because of where I was setting the text (i.e, in the onTextChanged callback, or the afterTextChanged) -- it was because I was using setText.

I got around the issue by calling:

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

Note: I still make the call in the afterTextChanged callback, though it works without warnings from ontextChanged as well.

Previous answer:

I was getting identical messages in logcat as well, though my scenario was slightly different. I wanted to read every character that came into EditText (or composed characters/pasted text), and then reset the EditText in question to a default initialisation string.

The clear text part works as per Johnson's solution above. However, resetting the text was problematic, and I'd get inputconnection warnings.

Initially, my onTextChanged(CharSequence s, ...) was defined as follows:

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

When onTextChanged(...) is called, the EditText is in readonly mode. I am not sure if this means we can't do more than call getText.clear() on it (setText(...) calls produce inputConnection warnings as well).

However, the callback afterTextChanged(Editable s) is the right place to set the text.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

This is, thus far, working without any warnings.


I was having the same problem. The warning appeared when the soft keyboard was activated in one of my EditTexts and the activity lose focus.

What I did was to hide the keyboard 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();
}

From the help documents

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

The InputConnection interface is the communication channel from an InputMethod back to the application that is receiving its input. It is used to perform such things as reading text around the cursor, committing text to the text box, and sending raw key events to the application.

In addition, further reading shows

getExtractedText(): This method may fail either if the input connection has become invalid (such as its process crashing) or the client is taking too long to respond with the text (it is given a couple seconds to return). In either case, a null is returned.

It appears to also monitor changes to such text, and alert changes.

To hunt the issue down you'll have to explore any database queries you are making, perhaps around listViews or lists in a layout.

If you don't have any views, for example it's happening randomly in the background, then i would suggest that its not a UI element issue, so ignore textfields and such. It could be a background service that's storing information in a cursor or requesting a cursor.

Also, does the issue arise from your app? or perhaps someone else's that you've installed recently. List the full logCat trace. Someone might recognise the issue.

I would hazard a guess that if you haven't written something specific around this that its someone elses log message, or perhaps that of a library your using?