InputMethodService.onUpdateSelection 是异步的吗?

Is InputMethodService.onUpdateSelection asynchronous?

我正在制作自定义 IME。我正在尝试跟踪用户何时手动更改文本的选择区域(而不是由于 IME 本身的操作而导致的选择更改,例如 commitText)。

为此,我正在跟踪 IME 期望选择位置的位置,并将其与 onUpdateSelection 中的实际选择位置进行比较。

例如,要提交我使用的文本:

private fun commitTextToInputConnection(text: String)
{
    moveExpectedSelection(text.length)
    service.currentInputConnection.commitText(text, 1)
}

但是,如果我这样做:

commitTextToInputConnection("Test1")
commitTextToInputConnection("Test2")

我发现按顺序会出现以下顺序:

1 - "Test1"

的 ExpectedSelectionPosition 更新

2 - "Test2"

的 ExpectedSelectionPosition 更新

3 - "Test1" 的 onUpdateSelection 被调用

4 - "Test2" 的 onUpdateSelection 被调用

显然,这个顺序不正确,导致我的输入法有一个不正确的 ExpectedSelectionPosition。

最奇怪的是,对于某些 Activity,ExpectedSelectionPosition 更新和 onUpdateSelection 调用的顺序总是以正确的顺序发生。对于其他活动,它们始终以相同(错误)的顺序出现。

这是怎么回事?我猜 commitText 等一定是异步的,导致了这种竞争条件,但文档中根本没有提到这一点。

是否有解决此问题的方法?或者,是否有任何其他方法可以专门监听用户手动触发的文本选择的变化,而不是 IME?

解决方案是使用 InputConnection.beginBatchEdit and InputConnection.endBatchEdit

在 'batchEdit' 块中对 currentInputConnection 所做的任何更改都集中到最后的单个 onUpdateSelection 调用中。

例如执行以下语句时:

service.currentInputConnection.beginBatchEdit()
commitTextToInputConnection("Test1")
commitTextToInputConnection("Test2")
service.currentInputConnection.endBatchEdit()

onUpdateSelection 仅在块中的所有更改都已完成后调用一次。