自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
输入法支持
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
我们对这些与屏幕相关的部分进行了更新,详情见下文:
对于在非默认屏幕上运行的应用,Android 10 支持使用软件键盘。
在非默认屏幕上运行的应用
关于输入法 (IME) 的软件键盘显示在哪个屏幕上,有不同的模式。软件键盘:
- 显示在目标应用所在的屏幕上。
- 显示在默认屏幕上(当目标应用在非默认屏幕上运行时)。
- 不显示在任何屏幕上。
系统会根据目标应用所在屏幕的设置确定要使用的模式。如需了解详情,请参阅:
WindowManager#setDisplayImePolicy()
WindowManager#getDisplayImePolicy()

图 1. 在辅助屏幕上显示 IME 软件键盘,包括目标应用
系统使用一个 IME,但可以在屏幕之间切换,以跟踪用户焦点。Android 10 默认所有第一方和第三方 IME 在创建时都会根据新屏幕的尺寸调整布局和大小。
如果屏幕 A 上有一个活动连接,并且屏幕 B 上的输入字段请求获得输入焦点,则会触发以下流程:
- 屏幕 B 上的输入字段发出一个新的输入连接。
InputMethodManagerService
检查是否应该批准该连接。
- 系统为该 IME 选择一个屏幕。如果屏幕 B 支持且允许显示 IME,则使用屏幕 B。否则,将选择设备的主屏幕。
- 如果所选屏幕并非来自屏幕 A,则重新建立连接。系统会销毁
InputMethodService
,然后重新创建它。
安全限制
系统不会在不属于自己的虚拟屏幕上显示 IME。这是出于安全方面的考虑,因为恶意应用可能会创建启用了系统装饰支持的虚拟屏幕,并从 Surface 读取用户敏感信息(例如输入预测和自定义背景)。
实现
在 Android 9(及更低版本)中,IME 只能在默认屏幕上使用,如屏幕输入法中所述。在 Android 10(及更高版本)中,用户可以通过切换焦点在不同屏幕上的不同输入文本字段之间切换,IME 窗口会移动到辅助屏幕上。
WindowManager
中的实现会跟踪输入法窗口(绘制软件键盘的 IME 窗口)和输入法目标窗口(IME 输入所在的窗口),以管理 IME 状态。
对于 InputMethodManagerService
(IMMS),将焦点移至另一个屏幕时,没有其他内置机制可以将屏幕更改传递给 InputMethodService
(IMS),并在运行时重新配置键盘布局。
为了实现在屏幕之间切换 IME 窗口,Android 10 实现了以下功能:
- 现在,可以在
DisplayContent#mInputMethodWindow
和 DisplayContent#mInputMethodTarget
中跟踪每个屏幕的 IME 和输入目标窗口,以便 WindowManager (WM) 可以单独管理每个屏幕的 IME 焦点状态。
- 在 IMMS 端,当通过
ViewRootImpl#handleWindowFocusChanged ->
InputMethodManager#onPostWindowFocus ->
IMMS#startInputOrWindowGainedFocus
收到来自外部屏幕的应用客户端焦点请求时,它会先取消绑定当前的输入法服务,然后再重新绑定该服务,以在 onServiceConnected()
中重新附加针对该外部屏幕的新 IME 窗口令牌。
- 在 IMS 端,收到
IMS#attachToken
后,将触发以下流程:
- 调用
ContextImpl#updateDisplay
,以在 InputMethodService#attachToken()
中更新服务上下文的屏幕。这会调用 ViewGroup#addView()
来调整键盘布局并适应检查当前上下文的目标屏幕。
- 调用
DisplayContent#setInputMethodWindowLocked()
之后,该实现使用 WindowProcessController
将进程级屏幕配置更改发送给 IME 进程,以替换资源和屏幕指标。
- 调用
onConfigurationChanged()
和 ViewGroup#addView()
之后,InputMethodService
客户端将获得合适的配置(其中包含正确的屏幕指标)来重新初始化输入视图。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-11。
[null,null,["最后更新时间 (UTC):2025-03-11。"],[],[],null,["# Input method editor support\n\nUpdates made to these display-specific areas are provided below:\n\n- [Apps running on a non-default display](/docs/core/display/multi_display/ime-support#non-default)\n- [Multi-session input method editor support](/docs/core/display/multi_display/ime-support#ime-multi)\n\nAndroid 10 supports\n[software keyboard](https://developer.android.com/guide/topics/text/creating-input-method)\nfor apps running on a non-default display.\n\nApps running on a non-default display\n-------------------------------------\n\nIn terms of which display shows the software keyboard of the Input Method Editor\n(IME), there are different modes. The software keyboard is shown on the:\n\n- *Same* display on which the focused app appears.\n- *Default* display while the focused app is running on a non-default display.\n- *No* display at all.\n\nThe system determines which mode to use based on the settings of the display\non which the focused app appears. For more details, see:\n\n- `WindowManager#setDisplayImePolicy()`\n- `WindowManager#getDisplayImePolicy()`\n\n**Figure 1.** IME software keyboard as it appears on secondary display,\nincluding target app\n\nThe system uses a single IME, but can shift between displays to follow\nuser focus. Android 10 automatically expects all first- and third-party IMEs to\nrevise the layout and resize according to the new display size when created.\n\nIf there's an active connection on display A, and an input field requests\ninput focus on display B, then the following flow occurs:\n\n1. A new input connection comes from the input field on display B.\n2. `InputMethodManagerService` checks if the connection should be approved.\n3. A display is selected for the IME. If display B supports showing the IME and is allowed to show it, then B is used. Otherwise, the primary device display is selected.\n4. If the selected display is not from display A, then the connection is re-established. `InputMethodService` is destroyed and then created again.\n\n### Security restriction\n\nThe system won't show an IME on virtual displays that aren't owned by the\nsystem. This is due to a security concern that a malicious app could create a\nvirtual display with enabled\n[system decorations support](/docs/core/display/multi_display/system-decorations)\nand read user-sensitive information from the surface, such as typing predictions\nand custom backgrounds.\n\n### Implementation\n\nIn Android 9 (and lower), the IME was only available on the default screen, as\ndescribed in [On-Screen\nInput methods](https://android-developers.googleblog.com/2009/04/updating-applications-for-on-screen.html). In Android 10 (and higher), a user can switch\nbetween different input text fields on different displays by switching focus,\nand the IME window moves to the secondary displays.\n\nThe implementation in `WindowManager` tracks the input method\nwindow (the IME window where the soft keyboard is drawn) and the input method\ntarget (the window where the IME input goes) to manage the IME state.\n\nFor `InputMethodManagerService` (IMMS), no other built-in mechanism can\npropagate the display change to `InputMethodService` (IMS) and\nreconfigure the keyboard layout at runtime when moving focus to another display.\n\nTo achieve the IME window switch between displays, Android\n10 implements the following:\n\n- The IME and input target window are now tracked per display in `DisplayContent#mInputMethodWindow` and `DisplayContent#mInputMethodTarget`, so that the WindowManager (WM) can manage the IME focus state independently of each display.\n- On the IMMS side, when an app client's focus request from the external display is received through `ViewRootImpl#handleWindowFocusChanged -\u003e\n InputMethodManager#onPostWindowFocus -\u003e\n IMMS#startInputOrWindowGainedFocus`, it first unbinds the current input method service and then rebinds the service to reattach the new IME window token for the external display in `onServiceConnected()`.\n- On the IMS side, after the `IMS#attachToken` is received, the following flow occurs:\n - `ContextImpl#updateDisplay` is called to update the service context's display in `InputMethodService#attachToken()`. This calls `ViewGroup#addView()` to revise the layout of the keyboard and adapt to the target display checking the current context.\n - After `DisplayContent#setInputMethodWindowLocked()` is called, the implementation sends process-level display configuration changes using the `WindowProcessController` to IME process to override resources and display metrics.\n - The `InputMethodService` client gets the correct configuration with the correct display metrics after `onConfigurationChanged()` and the `ViewGroup#addView()` call to reinitialize the input view."]]