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

更多相关文章

  1. GitHub 标星 2.5K+!教你通过玩游戏的方式学习 VIM!
  2. QT 环境的 Android(安卓)配置和编译
  3. Android异步线程与Bundle消息传递
  4. Android(安卓)ColorStateList使用方法
  5. Android6.0系统悬浮窗权限的问题解决方法
  6. android studio check for update 更新失败
  7. Android(安卓)手机上获取物理唯一标识码
  8. Android(安卓)常用技术框架的基本使用
  9. Retrofit +OKHttp简单封装使用

随机推荐

  1. Linux 中如何使用 Aria2 下载文件
  2. PHP mkdir() Permission denied 文件权限
  3. 分布式事务实践 解决数据一致性
  4. 图 -邻接表广度优先遍历(C语言)
  5. 图 - 邻接矩阵广度优先遍历(C语言)
  6. 图 - 邻接表深度优先遍历(C语言)
  7. 图 - 邻接矩阵深度优先遍历(C语言)
  8. 区块链与分享型数据库
  9. 在北京月薪从0.2K-13k,我是如何做到的
  10. mysql错误的数据对比方法