【问题标题】:getExtractedText on inactive InputConnection warning on androidandroid上非活动InputConnection警告上的getExtractedText
【发布时间】:2011-12-28 16:29:55
【问题描述】:

我在我的 logcat 中收到以下警告。

getExtractedText on inactive InputConnection

我无法找到背后的原因。请帮忙

【问题讨论】:

  • 我不明白这个问题有什么歧义/含糊/不完整?我在运行我的应用程序时在我的 logcat 中收到此警告,我想知道此警告的原因。
  • 我也在我正在开发的应用程序中看到了这个,我不知道它来自哪里或为什么。如果有人发现,请发表评论。它实际上显示了许多不同的警告,而不是“getExtractedText”。我还看到:“beginBatchEdit”、“endBatchEdit”、“getTextBeforeCursor”等等。
  • 是看这个问题的版主。如果不是,那么他们应该这样做,因为即使在 14 次投票之后他们仍然认为这个问题含糊不清,那么我不知道该说什么
  • 我同意,这也是我需要解决的问题。我不知道原因。
  • 你有什么代码导致这个错误?

标签: java android logcat


【解决方案1】:

我遇到了类似的问题。我的日志猫:

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 警告流的问题。但是,当用户在输入内容和按下按钮之间快速交替或在应用程序负载足够时按下按钮等时,这仍然容易出现问题。

幸运的是,我找到了另一种清除文本的方法:Editable.clear()。有了这个,我根本不会收到警告:

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

请注意,如果您希望清除所有输入状态而不仅仅是文本(自动文本、自动大写、多次点击、撤消),您可以使用TextKeyListener.clear(Editable e)

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

【讨论】:

  • 我也收到了 IInputConnectionWrapper 警告,我的应用程序几乎 ANR,方法 clear() 为我工作...超级奇怪的错误,在我设置 setText("");
【解决方案2】:

更新:

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

我通过调用解决了这个问题:

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

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

上一个答案:

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

明文部分按照上面约翰逊的解决方案工作。但是,重置文本是有问题的,我会收到输入连接警告。

最初,我的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();

    // ... 
}

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

【讨论】:

  • 我也遇到了同样的问题。我意识到,尽管您的解决方案使 InputConnection 警告消失,但我注意到在 hiddenKeyboardText.getText().clear();hiddenKeyboardText.append("some string"); 上调用了 afterTextChanged 方法,并且还应该考虑到这一事实。来自我的 +1!
  • @Nick true -- 确保if (isResettingKeyboard) return; 在最重要...
【解决方案3】:

我遇到了同样的问题。当在我的EditTexts 之一中激活软键盘并且活动失去焦点时出现警告。

我所做的是将键盘隐藏在 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();
}

【讨论】:

  • 这就是答案。确保在切换当前屏幕上的活动之前隐藏键盘。
【解决方案4】:

来自帮助文档

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

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

另外,延伸阅读展示

getExtractedText(): 如果输入连接无效,此方法可能会失败 (例如它的进程崩溃)或客户端花费的时间太长 回复文本(有几秒钟的时间返回)。在 无论哪种情况,都会返回 null。

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

要找出问题所在,您必须探索您正在进行的任何数据库查询,可能是围绕 listViews 或布局中的列表。

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

另外,问题是否出自您的应用程序?或者也许是您最近安装的其他人。列出完整的 logCat 跟踪。有人可能会认识到这个问题。

我会大胆猜测,如果你没有写一些具体的东西,那就是其他人的日志消息,或者你使用的库?

【讨论】:

  • 谢谢,我确实进行了 db 查询,但奇怪的是,在模拟器上运行应用程序时不会出现此警告,因此这实际上可能是由于我的设备上安装了其他一些应用程序。会朝这个方向看
  • 我认为最新的 logCat 显示您的消息与其他应用程序不同,经过过滤。不过,还没有充分使用它来确认这一点。您可以创建一个新的空应用程序,并观察 log cat 以查看是否发生错误,这将消除您的应用程序。从成为问题。
  • @frieza 不一定是其他应用程序。我已经用 sqlite 添加了 ArrayAdapter,现在我也在手机上收到了这个警告。我猜你在模拟器上看不到任何错误是因为它很慢并且性能阈值因此被禁用。
【解决方案5】:

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

这是由 List AdapterHeaderView 中的 Object 引起的。

我为 View 充气并声明了 Object 并在其上放置了一个 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);

Text Watcher 一切正常。

但是如果我在初始构建后重建了适配器。

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

那个HeaderView也被重建了。

该警告会显示,因为 Object 已被移除,而 Text Watcher 仍处于监视状态。

List AdapterObject 被替换了,我猜 Text Watcher 在发生这种情况时正在寻找另一个方向。

所以警告消失了,Text Watcher 奇迹般地找到了 HeaderViewObject。但它会失去焦点并记录该警告。

使用

JOBSadapter.notifyDataSetChanged();

修复了问题。

BUT 如果您在 Adapter 中有一个 Object,并且 Text Watcher 附加到 Adapter 适配器内的strong>对象。那么你可能需要做更多的工作。

尝试移除侦听器并在完成您可能正在做的任何工作后重新附加它。

Object.removeTextChangedListener();

Object.addTextChangedListener(null);

【讨论】:

    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

      ...我不知道我最终是如何在构建下初始化我的控制器的;但我做到了。

       `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 放置到我的表单后,这一切都消失了(如预期的那样)!

      【讨论】:

        【解决方案8】:

        当我不得不从 EditText 修改或获取文本并且它被聚焦时,我遇到了这个问题。

        所以在修改或获取它之前,我关闭了键盘并修复它。

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

        也许,您的问题有所不同。

        【讨论】:

          【解决方案9】:

          我已经解决了在 xml 上插入输入类型的问题,如下所示: android:inputType="none|text|textCapWords|textUri"

          在那之前是 android:inputType="text" 这解决了我的问题。

          【讨论】:

          • 什么也没帮我。
          【解决方案10】:

          Logcat 中的错误:非活动 InputConnection 上的 getTextBeforeCursor

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

          【讨论】:

            【解决方案11】:

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

            此外,它似乎是特定于设备的。我只在 Nexus 4 (Android 7.1) 上看到过它。模拟器(8.0、7.1)或 Nexus 5 上没有警告。

            【讨论】:

              【解决方案12】:

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

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

              【讨论】:

                【解决方案13】:

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

                【讨论】:

                  【解决方案14】:

                  它有一个非常简单的修复方法。 每当使用 Textformfield 时,只需输入 autofocus==true。 为我工作!

                  【讨论】:

                    猜你喜欢
                    • 2020-01-10
                    • 1970-01-01
                    • 2017-07-24
                    • 1970-01-01
                    • 2013-12-13
                    • 2020-11-15
                    • 2014-10-20
                    • 1970-01-01
                    相关资源
                    最近更新 更多