更多文章请关注:开发者技术前线
Android开发目前现状来说,开发者大部分时间花在UI的屏幕适配上,使用原生控件开发成本已不是那么的理想,鉴于很多项目保持和iOS一致的UI界面风格,至使移动UI开发成本花费更大的代价,因此目前结合H5和原生控件混合开发是解决UI适配的一种很好的选择, 因此基于网页形式的插件更新业务功能出现了,处于APP性能的考虑,Android也会使用java和native层(C,C++)进行结合。无论是哪种结合,其实原理都差不多,只要按照它的协议来是很容易的,今天我们仅对于H5和Java层结合的混合开发,了解WebViewJavascriptBridge的使用。
** 什么是JsBridge**
WebViewJavascriptBridge是移动UIView和Html交互通信的桥梁,用作者的话来说就是实现java(ios为oc)和js的互相调用的桥梁。替代了WebView的自带的JavascriptInterface的接口,使得开发者更方便的让js和native灵活交互,使我们的开发更加灵活和安全。
JSBridge的优点
Android API 4.4以前,谷歌的webview存在安全漏洞,网站可以通过js注入就可以随便拿到客户端的重要信息,甚至轻而易举的调用本地代码进行流氓行为,谷歌后来发现有此漏洞后,在API 4.4以后增加了防御措施,如果用js调用本地代码,开发者必须在代码申明JavascriptInterface, 列如在4.0之前我们要使得webView加载js只需如下代码:
mWebView.addJavascriptInterface(new JsToJava(), "myjsfunction");
4.4之后使用时需要在调用Java方法加入@JavascriptInterface注解,如果代码无此申明,那么也就无法使得js生效,也就是说这样就可以避免恶意网页利用js对客户端的进行窃取和攻击。 但是即使这样,我们很多时候需要在js调用本地java代码的时候,要做一些判断和限制,或者有的场景也会做些过滤或者对用户友好提示,甚至更复杂的Hybrid模式下,需要js和native之间进行交互通讯,拍照上传,因此原生的JavascriptInterface 就比较维护了,特此有了基于JavascriptInterface 封装的WebViewJavascriptBridge框架。
使用JsBridge正确姿势
1 添加依赖
Eclipse:
导入jar包
直接copy jar的源码到工程
JsBridge. jar可以到gitHub上直接下载。
Android Studio:
配置gradle
2 WebView需使用jsBridge的webView
JS和Native交互
JS是基于订阅和回调来实现Js和native交互的,我们需要在java中订阅,然后Js中回调,反之也可以。
3.1 Java
registerHandler()用来注册一个java函数,来实现js回调的handler,
第一个:订阅的方法名
第二个: 回调Handler , 参数返回js请求的resqustData,function.onCallBack()回调到js,调用function(responseData)
//必须和js同名函数,注册具体执行函数,类似java实现类
webView.registerHandler("submitFromWeb", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
function.onCallBack( data + “java”);
}
});
3.2 JS
Js代码需要用window.WebViewJavascriptBridge.callHandler同步回调java层注册的同名函数,这和java和c库的jni调用如出一辙,方法名必须和Java层保持一致
第一参数:方法名
第二个:js调用native的请求参数
第三个:js在被回调后具体执行方法,responseData为java层回传jsonStr.
window.WebViewJavascriptBridge.callHandler(
'submitFromWeb',
{'param': requsetData }, function(responseData) {
// do somrthing
});
案列实践
** 1.Activity**
初始化WebView,设置必要的参数。
需要自定义HandlerCallBack和WebViewClent;
加载网页 支持本地和远程
1 java调用js函数
js同样需要java注册订阅的同名函数
2 JS调用Java代码
反之js调用java代码
Js 订阅一个叫functionInJs的方法
3 注意事项
无论怎样形式的交互,Js 必须要初始化jsBridge
效果图:
代码展示
1 Acitivty
通过实例化webView,用法和安卓原生的view没多大区别,设置WebChromClient, 设置加载的html(同样支持网络和本地文件),接着我们需要给web注册和html端约定好的js方法名。代码列举的submitFromweb和js的执行的方法名一致,玩过NDK的JNI调用的朋友也知道必须和c代码之间有个约定,其实js桥和jni有点类似
2 js代码
这段代码不难理解,我们对上面的id为enter的Button注册了一个点击事件,点击后执行以下testClick()方法,依次类推,其他Button注册事件相同,当点击“发消息给Native”的按钮时,Js通过webWiew的jsBridage.send()发送一条数据给java层(密码和用户名),同时执行function()来执行应java层回调函数的。此demo中是把java返回的数据插入到ID为”show”的div里面去。
testClick1():此方法中调用callHandler来调用Java代码的submitFromweb同名函数,可以结合上面的Activty的代码理解下,此函数调用我们已在java已注册订阅
//必须和js同名函数,注册具体执行函数,类似java实现类。
3. H5
这里so ez ! 你不必care
h5实现文件上传
四 总结
通过以上的API介绍,代码示例,不难发现此框架的优雅和简便,对js和java双方来说,如果Html中的js需要调用java代码,而java代码没做任何实现,那么js中方法也是无效的,反之java代码注册的函数,没在js里去回调实现,那么Java层也是无法获取js中数据的,由此可见,此通信是双方支持的,必须由双方来约定,这样就避免了Android之前存在的js注入漏洞,也很大的提高了安全性,也可以保证我们的网页数据不被第三方的APP获取,具体来讲,列如我们的项目某一个web的h5界面,被系统浏览器或者其他第三方App的恶意加载,那么它的java代码想调用你的js函数,实现需要你的H5的Js先注册,不然跟本无法调用你的h5信息。这样保证了这个html数据的安全性,,第三方的浏览器可以加载预览你的网页,但是第三方java无法和你的的h5中的js交互通信的。同样加载我们自己的APP加载第三方的网页时候,我们可以对第三方网页进行一些行为的过滤,方便保护我们手机的安全,列如第三方可以获取本机地址时我们可以提示用户授权。
虽然H5并不属于插件的一种,但是借助h5我可以方便的去更新一些运营活动,和某些需要经常需要更换UI的业务功能的地方,由于本文是从CSDN迁移过来的,原文实在一年前写的,所以带来的坟贴感觉请见谅。
原文csdn请戳:这里
以上只JSBridge的使用姿势,以后再给大家解剖下JsBridge的内部实现。
项目地址
项目实例:https://github.com/NeglectedByBoss/JsBridge_Android
英文介绍:https://github.com/lzyzsd/JsBridge