输入法服务生命周期的错误

4

我正在编写自己的InputMethodService,我想要检测键盘何时弹出和关闭以便开始和停止执行操作。我有一个非常简单的 MyInput 类:

public class MyInput extends InputMethodService {
    private static final String TAG = "MyInput";

    @Override
    public View onCreateInputView() {
        Log.d(TAG, "onCreateInputView");
        LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        return inflater.inflate(R.layout.my_keyboard, null);
    }

    @Override
    public void onStartInput(EditorInfo attribute, boolean restarting) {
        super.onStartInput(EditorInfo attribute, boolean restarting);
        Log.d(TAG, "onStartInput restarting = " + restarting);
    }

    @Override
    public void onFinishInput() {
        super.onFinishInput();
        Log.d(TAG, "onFinishInput");
    }
}

我的视图正常弹出和弹回,但在日志中,我看到了一个非常奇怪的行为。每次键盘显示或隐藏时,两个函数都会被调用,这使我无法检测它是实际上在显示还是没有。

/** Keyboard not showing, I press an TextView **/
D  onFinishInput
D  onStartInput restarting = false
/** Keyboard showing, I press back **/
D  onFinishInput
D  onStartInput restarting = false
/** Keyboard not showing **/

我不明白为什么这样一个简单的例子不起作用。感谢任何帮助。

嗯,阅读Android API中InputMethodService的描述时提到:“当用户在输入目标之间切换时,您将收到对onFinishInput()和onStartInput(EditorInfo,boolean)的调用”。这可以解释您所经历的行为。http://developer.android.com/reference/android/inputmethodservice/InputMethodService.html - Lasse Samson
同意,我认为这个类的文档确实缺乏/没有真实反映。最终我使用了onWindowShown和onWindowHidden来检测键盘是否正在显示。 - chopchop
2
需要理解的关键是所有重要输入都通过InputMethodService进行处理,无论窗口是否可见。当活动首次显示时,它会创建一个InputConnection,处理基本事项,如音量键、返回键、dpad导航(如果设备有dpad)等。当用户聚焦于EditText时,您将获得基本InputConnection的OnFinishInput,然后获得EditText的InputConnection的onStartInput。通常可以通过检查EditorInfo.inputType == InputType.TYPE_NULL来区分这两种情况。 - j__m
1个回答

4

很不幸,官方的IME生命周期文档确实存在不足。通过大量的调试,我建立了一个更好的IME生命周期文档(最初是为自己创建的):

IME生命周期

关于你最初的问题,如果你想知道你的键盘当前是否显示,你不应该看onStartInput,而是需要看onStartInputView。在onStartInputViewonFinishInputView之间的调用中,你的键盘是可见的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接