Android 上的非活动 InputConnection 警告

我在日志中收到以下警告。

getExtractedText on inactive InputConnection

我找不到原因,请帮帮我

112569 次浏览

从帮助文件

Http://developer.android.com/reference/android/view/inputmethod/inputconnection.html

InputConnection 接口是来自 将 InputMethod 返回到正在接收其输入的应用程序 用于执行诸如阅读光标周围的文本之类的操作, 将文本提交到文本框,并将原始键事件发送到 申请。

此外,进一步的阅读显示

返回文章页面获取文本() : 如果输入连接无效,则此方法也可能失败 (例如它的进程崩溃)或客户端花费太长时间 使用文本响应(给它几秒钟返回) 无论哪种情况,都会返回一个 null。

它似乎还监视此类文本的更改,并通知更改。

为了解决这个问题,您必须研究正在进行的任何数据库查询,可能是在布局中的 listView 或列表周围。

如果你没有任何视图,例如它是在后台随机发生的,那么我建议这不是 UI 元素的问题,所以忽略文本字段之类的。它可以是在游标中存储信息或请求游标的后台服务。

另外,这个问题是由你的应用程序引起的吗?或者是你最近安装的别人的。列出完整的 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.

我的情况: 我有一个用户输入的 EditText 视图。当用户按下按钮时,EditText 将被清除。当我快速按下按钮时,大量不活跃的 InputConnection 条目流出。

例如:

editText.setText(null);

上面的 logcat 中的最后一行很好地说明了正在发生的事情。毫无疑问,InputConnection 被清除文本的请求淹没了。我试图修改代码,以检查文本长度,然后再尝试清除它:

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

这有助于缓解快速按下按钮不再导致 IInputConnectionWrapper 警告流的问题。然而,当用户在输入某些内容和按下按钮之间快速切换时,或者当应用程序处于足够负载时按下按钮时,这仍然容易出现问题,等等。

幸运的是,我找到了另一种清除文本的方法: Clear ()。有了它,我根本不会收到任何警告:

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

请注意,如果您希望清除所有输入状态,而不仅仅是文本(autotext、 autocap、 multiclick、 undo) ,则可以使用 Clear (可编辑 e)

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

我也有同样的问题。当我的一个 EditTexts中的软键盘被激活并且活动失去焦点时,警告出现了。

我所做的是将键盘隐藏在 onPuse ()中;

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

我自己解决了这个问题,也许你也有同样的问题。

这是由 列表适配器标题视图反对引起的。

我给一个 观景充气,然后声明是 反对,再放一个 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
}
});

将其添加到 列表适配器并构建适配器。

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

一切正常,短信观察者正常工作。

如果我在初始构建之后重新构建适配器,那么可以使用。

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

那个 标题视图也是重建的。

这个警告会显示出来,因为 反对被移除了,而文本监视器仍然在监视它。

列表适配器反对被替换了,我猜 短信观察者在事情发生的时候,正在睁一只眼闭一只眼。

所以警报响了然后 短信观察者奇迹般地找到了 标题视图反对。但它会分散注意力,并记录警告。

吸毒

JOBSadapter.notifyDataSetChanged();

解决了问题。

但是 如果你在 适配器内部有一个 反对,并且 短信观察者连接到 适配器内部的 反对。那么你可能需要多做一点工作。

尝试删除监听器,并在完成任何工作之后再次附加它。

Object.removeTextChangedListener();

或者

Object.addTextChangedListener(null);

除了 antoniom 的回答,确保任何需要做的进一步操作都是在隐藏键盘之后完成的,所以如果你像下面这样隐藏了键盘:

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

,您需要有后续的操作后执行键盘隐藏,如下所示:

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

更新:

我收到 InputConnection 警告的原因不是因为我在哪里设置了文本(例如,在 onTextChanged回调中,或者在 afterTextChanged中)——而是因为我在使用 setText

我打电话回避了这个问题:

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

注意: 我仍然在 afterTextChanged回调中进行调用,尽管它也可以在没有来自 ontextChanged的警告的情况下工作。

回答:

我在 logcat 中也收到了相同的消息,尽管我的情况略有不同。我想读取每个进入 EditText (或组合字符/粘贴文本)的字符,然后将有问题的 EditText 重置为默认初始化字符串。

清晰的文本部分按照 Johnson 上面的解决方案工作。然而,重新设置文本是有问题的,并且我会得到 inputconnect 警告。

最初,我的 onTextChanged(CharSequence s, ...)定义如下:

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

当调用 onTextChanged(...)时,EditText 处于只读模式。我不确定这是否意味着我们只能对它调用 getText.clear()(setText(...)调用也会产生 inputConnection 警告)。

但是,回调 afterTextChanged(Editable s)是设置文本的正确位置。

@Override
public void afterTextChanged(Editable s) {


if (isResettingKeyboard)
return;


resetKeyboardString();


// ...
}

到目前为止,这是在没有任何警告的情况下工作的。

当我需要从 EditText 中修改或获取文本时,我遇到了这个问题,而且它是集中的。

因此,在修改或得到从它,我关闭键盘,我修复它。

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

也许,你的问题不一样。

我已经像下面这样解决了在 xml 上插入输入类型的问题: Android: inputType = “ none | text | textCapWords | textUri”

之前是 android: inputType = “ text” 这解决了我的问题。

Logcat 错误: getTextbefore 游标在非活动的 InputConnection 上

解决方案: 隐藏你的输入键盘并运行应用程序。

在清除 EditText 之前隐藏软件键盘-不会显示警告。

还有,好像是 特定设备。我只在 Nexus 4(Android 7.1)上看到过。模拟器(8.0,7.1)或 Nexus 5上没有警告。

我的问题是由于将 EditText的可见性设置为 GONE,然后在每次用户输入字符时立即将其设置为 VISIBLE,因为我在每次文本改变时都对输入进行验证,在某些情况下需要隐藏视图。

因此,解决方案是避免在 UI 或状态更新之间将 View 或 Layout 的可见性设置为 GONE,因为 EditText可能会失去焦点

如果遇到同样的问题,通过将我的无状态小部件转换为有状态小部件来修复它,你可以尝试一下

... 我不知道我是如何在构建中初始化我的控制器的,但是我做到了。

 `Widget build(BuildContext context) {
final _formKey = GlobalKey<FormState>();
final prodName = TextEditingController();
final prodDesc = TextEditingController();
final prodPrice = TextEditingController();
...`

代替

`final _formKey = GlobalKey<FormState>();
final prodName = TextEditingController();
final prodDesc = TextEditingController();
final prodPrice = TextEditingController();
...
Widget build(BuildContext context) {`

当然,在我正确地将控制器和 GlobalKey 放置到我的表单之后,一切都消失了!

它有一个非常简单的解决方案。 无论何时使用 Textformfield,只需将 autofocus = = true。 对我有用!