Alternative way for communication between WebView and native

前端 未结 2 1622
星月不相逢
星月不相逢 2020-12-10 21:22

I am using WebView and a lot of JavaScript in my native application. If JS side wants to call native functions it\'s rather smooth using JavaScriptInterfa

相关标签:
2条回答
  • 2020-12-10 21:30

    I don't know how to get an alternate communication model working, but I think I've found a workaround for the loadUrl-hides-the-keyboard issue: https://stackoverflow.com/a/18776064/513038. Does that help any?

    0 讨论(0)
  • 2020-12-10 21:53

    I have the following code which uses java reflection to call JavaScript from Java. It avoids the following loadUrl bugs: 1. loadUrl may hide keyboard when your focus in a input. 2. loadUrl cannot be called too often.

    Hopefully this helps:

    public class AdvancedWebView extends WebView {
        private static final int EXECUTE_JS = 194;
        Method sendMessageMethod;
        Object webViewCore;
        boolean initFailed = false;;
        InputMethodManager imm;
    
    
        public AdvancedWebView(Context context, AttributeSet attrs) {
            super(context, attrs);
            imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
            this.getSettings().setJavaScriptEnabled(true);
            this.initReflection();
        }
    
        @SuppressWarnings("rawtypes")
        private void initReflection() {
            Object webViewObject = this;
            Class webViewClass = WebView.class;
            try {
                Field f = webViewClass.getDeclaredField("mProvider");
                f.setAccessible(true);
                webViewObject = f.get(this);
                webViewClass = webViewObject.getClass();
            } catch (Throwable e) {
                // mProvider is only required on newer Android releases.
            }       
    
            try {
                Field f = webViewClass.getDeclaredField("mWebViewCore");
                f.setAccessible(true);
                webViewCore = f.get(webViewObject);
                if (webViewCore != null) {
                    sendMessageMethod = webViewCore.getClass().getDeclaredMethod("sendMessage", Message.class);
                    sendMessageMethod.setAccessible(true);      
                    System.out.println("sendMessageMethod-----"+sendMessageMethod);
                }
                hasIntercepted = true;
            } catch (Throwable e) {
                hasIntercepted = false;
                //Log.e(LOG_TAG, "PrivateApiBridgeMode failed to find the expected APIs.", e);
            }finally{
                if(sendMessageMethod == null)
                {
                    hasIntercepted = false;
                }
            }
        }
    
        private void loadJs(String url) {
            if (sendMessageMethod == null && !initFailed) {
                initReflection();
            }
            // webViewCore is lazily initialized, and so may not be available right away.
            if (sendMessageMethod != null) {
                //String js = popAndEncodeAsJs();
                Message execJsMessage = Message.obtain(null, EXECUTE_JS, url);
                try {
                    sendMessageMethod.invoke(webViewCore, execJsMessage);
                } catch (Throwable e) {
                    //Log.e(LOG_TAG, "Reflection message bridge failed.", e);
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题