技术改变生活

Technology changes life,Life-long learning

安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析

JsBridge:安卓和javascript最流行的交互方式,有以下4种方式可以实现交互传值

  • 1,addJavascriptInterface:针对Android 4.2(API 17)及以上,只有标有@JavascriptInterface注解的public方法才能从js调用。而对targetSdkVersion为API Level 16及以下的app,js可以调用Java所有的public方法。
    通过public void addJavascriptInterface (Object object, String name)方法把对象传递给js,
  • 2, loadUrl:可以实现安卓调用js,通过webview.loadUrl(“javascript:jsMethod()”);字符串里的javascript: 是固定写法,后面的jsMethod可以替换成你js代码里的方法。也可以通过”javascript:jsMethod(” + jsonParams + “)”;传递数据给js。这个缺点:如果js方法返回数据,这里会发生重定向。解决办法是用evaluateJavascript
  • 3,evaluateJavascript:安卓4.4以后可以实现安卓调用js,安卓可以传数据给js,并且可以获取js方法的返回值。
    缺点:必须大于api19(4.4)才可以使用
  • 4,shouldOverrideUrlLoading:通过这个方法拦截url,并解析url携带的参数,如:qiushi://setH5Info?params={“title”%3A”商品详情”}

js调用安卓

  • webView.addJavascriptInterface()
  • WebViewClient.shouldOverrideUrlLoading()

安卓调用js

  • webView.loadUrl();
  • webView.evaluateJavascript()

下面我门结合代码具体讲解下这4中方式的具体代码实现

  • 首先我们要在androidstudio的assets文件夹下面定义下面html。

    《安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析》

    image.png

一,addJavascriptInterface 实现js调用安卓

  • 针对Android 4.2(API 17)及以上
  • js可以调用安卓方法
  • 通过调用安卓方法可以实现安卓向js传递数据
  • 要被js调用的方法必须加@JavascriptInterface注释
  • 使用这个方法前必须设置webview.getSettings().setJavaScriptEnabled(true);

主要通过
public void addJavascriptInterface(Object object, String name) {}方法实现js调用安卓原生代码,简单讲解下两个参数。
object:安卓对象
name:安卓对象的别名。
如我们定义
webview.addJavascriptInterface(JavaH5Activity.this, “androidObject”);就是把JavaH5Activity的实例命名为androidObject传递给js。
我们在js里的调用如下
<div id=”div” onclick=”window.androidObject.androidMethod()”></div>

完整代码如下:

js的代码如下

在js里我们使用window.androidObject.androidMethod();调用安卓的方法,进而获取到安卓传递过来的数据。
如下图

《安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析》

手机运行效果

《安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析》

log日志

同时看日志,我们能看到js成功的调用了安卓的方法,并获取到了安卓native传递过来的数据。

二,shouldOverrideUrlLoading 实现js调用安卓

js通过重定向出发安卓拦截,重定向的url被shouldoverrideurlloading拦截到。分发拦截到的信息指挥安卓做事情。
简单的重定向的代码如下

这里的url:“qiushi://setH5Info?params=%7B%22title%22%3A%22%E5%95%86%E5%93%81%E8%AF%A6%E6%83%85%22%7D”是url编码后的,编码前的样式如下。这里涉及到url传递汉子需要编码的问题。以后有机会再做url编码的讲解。

《安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析》

URL编码

安卓端的代码做拦截解析。

打印结果如下

《安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析》

日志

这里我们可以看到安卓成功拦截到了url并解析出来了url里的数据,这样js就可以通过这些数据指挥安卓做事情了。并且也可以做到js传递数据给安卓的效果。

三,loadUrl:安卓调用js

  • 安卓通过webview的loadUrl可以调用js方法
  • 安卓传递数据给js
  • js不能返回数据,因为js返回数据的话,会导致重定向问题。下面会做讲解。
    安卓端的代码如下

js的代码如下:

运行结果如下

《安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析》

运行结果

可以看到我们把数据jsonParams传递给了js并显示在了h5页面上。
上js代码里的 //return ‘987654321’;注释如果解开,会发生请求重定向的问题,如下图

《安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析》

image.png

这里不能通过安卓调用js代码获取js数据,那该怎么办呢,下面的方法正好可以弥补这个缺陷。

四,evaluateJavascript:安卓调用js

  • 必须大于api19(4.4)才可以使用
  • 可以实现安卓和js的双向传递数据
    安卓端的代码如下

js的代码如下

运行结果如下

《安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析》

运行结果

打印日志如下

《安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析》

image.png

我们可以看到,通过evaluateJavascript可以实现安卓调用js代码。并且安卓的数据可以传递给js,js的数据也可以传递给安卓。

JSBridge的原理解析

JSBridge:是一座用JavaScript搭建起来的桥,替代了WebView的自带的JavascriptInterface的接口,使得我们的开发更加灵活和安全。一端是web,一端是native,他可以根据web和native约定好的规则来通知native要做什么,从而实现Android和Javascript之间的交互

JSBridge的原理可以总结为以下三点:

  • 1、Android通过loadUrl(url)调用JS对象,可以在URL内传递参数。
  • 2、JS调用Android是通过shouldOverrideUrlLoading拦截uri。
  • 3、JsBridge将数据封装成Message,然后放进Queue,再将Queue通过协议进行传输。

原文始发于:安卓webview原生和JavaScript(js)交互传值的4种方式 +java和js交互 +安卓JsBridge原理解析

点赞