
作者丨 看书的小蜗牛 链接丨 https://www.jianshu.com/p/c6346796722f 电商或者内容类APP中,H5通常都会占据一席之地,Native跟H5通信会必不可少,比如某些场景H5通知native去分享,native通知H5局部刷新等,Android本身也提供这样的接口,比如addJavascriptInterface、loadUrl("javascript:…"),而需要支持的能力也要是双工的。
- H5通知Native(可能需要处理回调),
- Native通知H5(也可能需要处理回调)
实现这种机制的方式并不唯一,但使用不当经常会引入很多问题,比如: H5同Native需要一个中间js文件,实现简单的通信协议,这个js文件有的产品做法是让前端自己加载,有的做法是客户端注入,也就是通过loadUrl("javascript:…")注入。 采用客户端注入这种方式就多少有问题,因为没有一个很合适的时机既保证注入成功,又保证注入及时。 如果在onPageStarted时注入,很多手机会注入失败,如果onPageFinished时注入,又太迟,导致很多功能打折扣。 再比如: 有些人通过prompt方式实现H5通知Native,而prompt是一个可能产生问题的同步方法,一旦无法返回,整个js环境就会挂掉,导致所有H5页面都无法打开,下面简单说下两种实现,一是通过addJavascriptInterface,另一种就是通过prompt。
方案一:借助WebView.addJavascriptInterface实现H5与Native通信
WebView的addJavascriptInterface方法允许Natvive向Web页面注入Java对象,之后,在js中便可以直接访问该对象,使用@JavascriptInterface注解的方法。 比如通过如下代码向前端注入一个名字为mJsMethodApi的java对象
class JsMethodApi {
/**
* js调用native,可能需要回调
*/ @JavascriptInterfacepublic void callNative(String jsonString) {
... }}webView.addJavascriptInterface(new JsMethodApi(), "mJsMethodApi");
在前端的js代码中,是可以直接通过mJsMethodApi.callNative(jsonString)通知Native的,而且通过addJavascriptInterface注入的对象在H5的任何地方都可以调用,不存在注入时机跟注入失败的问题,在H5的head里调用都没问题。
<head> <script type="text/javascript" >
JsMethodApi.callNative('头