Android WebView 中 JS 与Java之间通信

Java调用JS

在WebView中,Java调用JS的方法,实现方式是相对简单的。
采用如下形式即可:

 WebView.loadUrl(“javascript:function()”)

查阅官方文档也给出了相应实例:

 class JsObject {
    @JavascriptInterface
    public String toString() { return "injectedObject"; }
 }
 webview.getSettings().setJavaScriptEnabled(true);
 webView.addJavascriptInterface(new JsObject(), "injectedObject");
 webView.loadData("", "text/html", null);
 webView.loadUrl("javascript:alert(injectedObject.toString())");

JS调用Java

JS调用Java方法,需要采用WebView提供的一些API,同时需要前端同学和App同学约定一些类名和方法名。

方案一

setJavaScriptEnabled
调用WebSettings.setJavaScriptEnabled()启用支持JavaScript功能

addJavaScriptInterface
void addJavascriptInterface (Object object, String name)

此方法将提供的Java对象注入WebView中。该对象使用提供的名称(即name)注入到主框架的JavaScript上下文中。这允许从JavaScript访问Java对象的方法。对于定位到API级别JELLY_BEAN_MR1及更高版本的应用程序,只能使用有@JavascriptInterface注解的公共方法可以从JavaScript访问。对于针对API级别JELLY_BEAN或更低版本的应用程序,可以访问所有公共方法(包括继承的方法),请参阅下面的重要安全说明以了解其含义。

注意 在注入对象之前应该启用JavaScript。并且只用页面被重新加载,注入的对象才会出现在JavaScript中。

 class JsObject {
    @JavascriptInterface
    public String toString() { return "injectedObject"; }
 }
 webview.getSettings().setJavaScriptEnabled(true);
 webView.addJavascriptInterface(new JsObject(), "injectedObject");

在此例中,向WebView注册一个名叫injectedObjectJsObjectJava对象,然后在JS中可以通过injectedObject.toString()访问此方法,最终可以调用到Java代码中,从而实现了JS与Java代码的交互。

当然这种方式在Android 4.2版本一下存在安全漏洞,具体请查看Android WebView的Js对象注入漏洞解决方案

方案二

在WebView有一个方法,叫setWebChromeClient,可以设置WebChromeClient对象,而这个对象中有三个方法,分别是onJsAlert,onJsConfirm,onJsPrompt,当js调用window对象的对应的方法,即window.alert,window.confirm,window.prompt,WebChromeClient对象中的三个方法对应的就会被触发,我们是不是可以利用这个机制,自己做一些处理呢?答案是肯定的。


public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        return false;
}

相对于alert、comfirm的使用场景,prompt就显得特别少,使用它实现JS调用Java的功能再合适不过了。

Android JSBridge的原理与实现

规定协议:

jsbridge://className:callbackAddress/methodName?jsonObj

以WindVane为例,

hybrid://OptionsMenuJsBridge:19778/noteList?{}
hybrid://OptionsMenuJsBridge:19780/modifyNote?{“id”:33184}

而协议需要通过编写JS代码以通用的方式生成,前端只需要关注调用方式即可

window.WindVane.call(className, methodName, jsonObj, successCallback, failureCallback);

在Java中,会以defaulatValue.equals(“wv_hybrid”)作为判断条件来处理响应协议,执行具体指定的方法和解析参数

    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        if(TaoLog.getLogStatus()) {
            TaoLog.i("WVWebChromeClient", "onJsPrompt: %s; defaultValue: %s; url: %s", new Object[]{message, defaultValue, url});
        }

        if(view instanceof IWVWebView && WVEventService.getInstance().onEvent(2003, (IWVWebView)view, url, new Object[]{message, defaultValue, result}).isSuccess) {
            return true;
        } else if(defaultValue != null && defaultValue.equals("wv_hybrid:")) {
            WVJsBridge.getInstance().callMethod((WVWebView)view, message);
            result.confirm("");
            return true;
        } else {
            return false;
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青菜小王子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值