Android输入法显示方式大概分为两种:用户手动点击输入框和应用程序设置了输入法自动显示
本文基于Android9.x来分析
目录
1 :viewClicked流程
1.1 viewClicked
1.2 checkFocus
1.3 startInputInner
1.4 startInputOrWindowGainedFocus
1.5 startInputLocked
1.6 startInputUncheckedLocked
1.7 attachNewInputLocked
1.7.1 处理返回的结果
2:showSoftInput流程
2.1 showSoftInput
2.2 IMMS#showSoftInput
2.3 showCurrentInputLocked
2.4 IMS$InputMethodImpl$showSoftInput
2.5 dispatchOnShowInputRequested
2.6 IMS$showWindow
2.7 showWindowInner
2:从用户点击输入框开始
EditText本身是TextView的子类,触摸事件的起点在TextView的onTouchEvent方法中
if (touchIsFinished && (isTextEditable() || textIsSelectable)) {
// Show the IME, except when selecting in read-only text.
final InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
if (isTextEditable() && mEditor.mShowSoftInputOnFocus && imm != null) {
imm.showSoftInput(this, 0);
}
// The above condition ensures that the mEditor is not null
mEditor.onTouchUpEvent(event);
handled = true;
}
2.1:viewClicked
protected void viewClicked(InputMethodManager imm) {
if (imm != null) {
imm.viewClicked(this);
}
}
2:2:InputMethodManager::viewClicked
public void viewClicked(View view) {
final boolean focusChanged = mServedView != mNextServedView;
checkFocus();
synchronized (mH) {
if ((mServedView != view && (mServedView == null
|| !mServedView.checkInputConnectionProxy(view)))
|| mCurrentTextBoxAttribute == null || mCurMethod == null) {
return;
}
try {
if (DEBUG) Log.v(TAG, "onViewClicked: " + focusChanged);
mCurMethod.viewClicked(focusChanged);
} catch (RemoteException e) {
Log.w(TAG, "IME died: " + mCurId, e);
}
}
}
mCurMethod代表的是一个binder代理对象,对应的是
IInputMethodSessionWrapper
2.3:IInputMethodSessionWrapper::viewClicked
@Override
public void viewClicked(boolean focusChanged) {
mCaller.executeOrSendMessage(
mCaller.obtainMessageI(DO_VIEW_CLICKED, focusChanged ? 1 : 0));
}
case DO_VIEW_CLICKED: {
mInputMethodSession.viewClicked(msg.arg1 == 1);
return;
}
InputMethodSession对应的是一个接口,其实现类为AbstractInputMethodSessionImpl,AbstractInputMethodSessionImpl本身是一个抽象类,InputMethodSessionImpl有继承它,所以最终调用的是InputMethodSessionImpl的viewClicked
2.4::InputMethodSessionImpl::viewClicked
public void viewClicked(boolean focusChanged) {
if (!isEnabled()) {
return;
}
InputMethodService.this.onViewClicked(focusChanged);
}
2.5:InputMethodService::onViewClicked
public void onViewClicked(boolean focusChanged) {
// Intentionally empty
}
2.6:TextView::checkFocus
public void checkFocus() {
if (checkFocusNoStartInput(false)) {
startInputInner(InputMethodClien