对的WebView和本地之间的通信替代方法 [英] Alternative way for communication between WebView and native

查看:232
本文介绍了对的WebView和本地之间的通信替代方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的WebView 在我的本机应用程序有很多的JavaScript。如果JS一边要调用本地函数这是相当流畅使用 JavaScriptInterface 。但是,如果原生要调用JS功能,它不是那么容易的。我试过两个解决方案迄今:

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 JavaScriptInterface. However, if native wants to call JS function it's not so easy. I've tried two solutions so far:


  • 调用使用loadURL 的javascript:东西() URL - 当用户在键盘上打字的东西,因为不能接受的WebView 在功能执行后隐藏它

  • 询问机端的功能,每x秒($ P $由字符串对象psented)和
    的eval()上一个结果 - 有时是1秒钟我得到50-60秒后,这些请求设定的时间间隔后!

  • calling loadUrl method with javascript:something() URL - not acceptable since when user is typing something on keyboard WebView is hiding it after function execution
  • asking native side for functions every x seconds (presented by String object) and call eval() on a result - sometimes after setting interval for 1 seconds I was getting those requests after 50-60 seconds!

我想知道是否有任何其他方式来完成这种通信模式。比方说,建立内部的应用程序的本地插座 / HTTP /东西,别的服务器并给<$ C $它访问C>的WebView 。我在寻找任何提示如何(如果可能的话)做到这一点。

I am wondering if there's any other way to accomplish this communication model. Let's say create local Socket/HTTP/something-else server inside app and give access for it to WebView. I am looking for any tips how (if it's possible) do that.

推荐答案

我有以下的code,它使用Java反射从Java调用JavaScript。它避免以下的错误使用loadURL:
  1.使用loadURL可能隐藏键盘时,你的焦点在输入。
  2.使用loadURL不能称之为过于频繁。

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.

希望这有助于:

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);
            }
        }
    }
}

这篇关于对的WebView和本地之间的通信替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆