当前位置:   article > 正文

Android WebView拉起软键盘的流程浅析_android webview 如何调起输入法

android webview 如何调起输入法

前言

此文是flutter_hybird_webview 跨进程渲染的实践技术分享开发过程中的研究笔记之一,如有错误还望指出。

源码分析

首先我们大致看一下webview的继承结构:

public class WebView extends MockView {
    ...
}

public class MockView extends FrameLayout {
    ...
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

可以知道,webview的模型及基本行为规范,是遵从view的,那么我们可以推测其操作软键盘的方式与本地(app)的操作方式可能是一致的,为此我们先来了解一下app是如何拉起软键盘的。

关于MockView的个人理解及在开发中的应用,将会在其他文章做分享。
  • 1

App 拉起软键盘流程

拉起软键盘一般如下:

private void test() {
    //请求一下焦点
    editText.requestFocus();
    //获取 imm 并调用对应方法
    InputMethodManager manager = ((InputMethodManager)getContext()
                            .getSystemService(Context.INPUT_METHOD_SERVICE));
    if (manager != null) 
        manager.showSoftInput(v, 0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

从上面的代码可以大致推出这是一个跨进程行为,内部流程大致如下:

  1. 通过getContext().getSystemService(Context.INPUT_METHOD_SERVICE))获取IMM
  2. IMM本身并不是输入进程的代理,它内部IInputMethodManager才是真正的binder代理
//当调用manager.showSoftInput(v, 0);时

public boolean showSoftInput(View view, int flags, ResultReceiver resultReceiver) {
    // ...省略部分代码
    synchronized (mH) {
        if (mServedView != view && (mServedView == null
                || !mServedView.checkInputConnectionProxy(view))) {
            return false;
        }

        try {
            //IInputMethodManager 的实例
            return mService.showSoftInput(mClient, flags, resultReceiver);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3.随后,输入进程会拉起软键盘,并将对应的的keyEvent传回到app进程,最终通过dispatchKeyEvent(KeyEvent event)方法,分发到顶部windowdecor view并被内部view消费。

至此,对于软键盘(app端)的拉起我们有了一个大致了解,基于此我们来分析一下webview的拉起过程。

webview 拉起软键盘流程

简单地讲webview本质chromium,而chromium的源码是非常庞大的, 直接去扒源码可以说是大海捞针。

 其工作渲染流程,我将在其它文章做介绍
  • 1

由上面一节我们知道webview的行为与view大致相同,那么我们可以尝试逆推,首先我们复写getSystemService方法:

@Override
public Object getSystemService(@NonNull String name) {
    if(name.equals(Context.INPUT_METHOD_SERVICE)) {
        //在方法内部,我们输出当前线程的堆栈信息
        inputToggleDelegate.inputServiceCall();
    }
    return super.getSystemService(name);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

随后,我们打开一个带有输入框的网站,并点击输入框可以得到下面的log:

webview_ime_log.png

通过log,可得软键盘的控制是通过ImeAdapterImpl.java - Chromium Code SearchupdateState(...)方法来实现的。
其内部会调用showSoftKeyboard()方法 :

private void showSoftKeyboard() { 
    if (!isValid()) return; 
    if (DEBUG_LOGS) Log.i(TAG, "showSoftKeyboard"); 
    View containerView = getContainerView(); 
    mInputMethodManagerWrapper.showSoftInput(containerView, 0, getNewShowKeyboardReceiver()); 
    if (containerView.getResources().getConfiguration().keyboard 
            != Configuration.KEYBOARD_NOKEYS) { 
        mWebContents.scrollFocusedEditableNodeIntoView(); 
    } 
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

接着看一下mInputMethodManagerWrapper.showSoftInput():

@Override 
public void showSoftInput(View view, int flags, ResultReceiver resultReceiver) { 

    //...省略部分代码
    showSoftInputInternal(view, flags, resultReceiver); 
}

private void showSoftInputInternal(View view, int flags, ResultReceiver resultReceiver) { 
    StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); // crbug.com/616283 
    try { 
        //通过WindowAndroid的弱引用获得activity,并最终取得imm
        InputMethodManager manager = getInputMethodManager(); 
        if (manager != null) { 
            boolean result = manager.showSoftInput(view, flags, resultReceiver); 
            if (DEBUG_LOGS) Log.i(TAG, "showSoftInputInternal: " + view + ", " + result); 
        } 
    } finally { 
        StrictMode.setThreadPolicy(oldPolicy); 
    } 
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

到了这里,就与我们上一节的流程汇合了,而后面的分发消费则是大同小异。

WebView拉起软键盘的流程分析到此便结束了,谢谢大家阅读。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/257449
推荐阅读
相关标签
  

闽ICP备14008679号