Android混合开发之WebViewJavascriptBridge实现JS与java安全交互
来源:互联网 发布:牡丹江管理局电视网络 编辑:程序博客网 时间:2024/05/17 23:26
Android混合开发之WebViewJavascriptBridge实现JS与java安全交互
前言:
为了加快开发效率,目前公司一些功能使用H5开发,这里难免会用到Js与Java函数互相调用的问题,这个Android是提供了原生支持的,不过存在安全隐患,今天我们来学习一种安全方式来满足Js与java互相调用的需求。它就是WebViewJavascriptBridge。
学习动机:
先看下之前的解决办法:Android混合开发之WebView与Javascript交互
最近棒棒安全的一个市场推广来我们公司推广他们的产品,当时也没太引起我的注意,后来这个市场推广人员把我们的app的进行了他们的安全验证,然后发给我一份检测报告,关于WebView的检测内容大致如下:
其实目前公司采用H5的业务都是相对不是很重要的一些业务,而且安全性要求相对比较低,不过作为技术负责人的我,觉得现在很有必要尽快寻找一个相对安全的方式来解决这个问题,算是未雨绸缪吧。经过搜过资料寻找的解决办法就是使用WebViewJavascriptBridge来实现Js与Java的互相调用。
WebViewJavascriptBridge介绍:
WebViewJavascriptBridge是WebView和Js交互通信的桥梁,用作者的话来说就是实现java和js的互相调用的桥梁。替代了WebView的自带的JavascriptInterface的接口,使得开发者更方便的让js和native灵活交互,使我们的开发更加灵活和安全。
目前实现JSBridge的开源框架很多,这里采用的hi大头鬼hi写的开源框架:https://github.com/lzyzsd/JsBridge
WebViewJavascriptBridge使用方式:
1.)添加配置信息
project的build.gradle中添加如下配置
allprojects { repositories { jcenter() maven { url "https://jitpack.io" } }}
在module的build.pradle中添加如下配置
dependencies { compile 'com.github.lzyzsd:jsbridge:1.0.4'}
2.)用BridgeWebView替换WebView
<com.github.lzyzsd.jsbridge.BridgeWebView android:id="@+id/test_bridge_webView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/>
3.)Js调用Java方法并传递数据
可以通过registerHandler()用来注册一个java函数,来实现js回调的handler
//必须和js同名函数,注册具体执行函数,类似java实现类。 //第一参数是订阅的java本地函数名字 第二个参数是回调Handler , 参数返回js请求的resqustData,function.onCallBack()回调到js,调用function(responseData) mBridgeWebView.registerHandler("submitFromWeb", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { Log.e(TAG, "指定Handler接收来自web的数据:" + data); function.onCallBack("指定Handler收到Web发来的数据,回传数据给你"); } });
Js调用指定函数并传递参数
function testClick1() { //调用本地java方法 //第一个参数是 调用java的函数名字 第二个参数是要传递的数据 第三个参数js在被回调后具体执行方法,responseData为java层回传数据 var data='发送消息给java代码指定接收'; window.WebViewJavascriptBridge.callHandler( 'submitFromWeb' ,data , function(responseData) { bridgeLog('来自Java的回传数据: ' + responseData); } ); }
也可以mBridgeWebView.setDefaultHandler()设置DefaultHandler,这样可以接收Js通过window.WebViewJavascriptBridge通过send的所有数据
mBridgeWebView.setDefaultHandler(new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { Log.e(TAG, "DefaultHandler接收全部来自web的数据:"+data); function.onCallBack("DefaultHandler收到Web发来的数据,回传数据给你"); } });
js实现向java发送数据
function testClick() { //发送消息给java代码 var data = '发送消息给java代码全局接收'; window.WebViewJavascriptBridge.send( data , function(responseData) { bridgeLog('来自Java的回传数据: ' +responseData); } ); }
4.)Java调用Js方法并传递参数
//注册事件监听 function connectWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge) } else { document.addEventListener( 'WebViewJavascriptBridgeReady' , function() { callback(WebViewJavascriptBridge) }, false ); } }
在使用WebViewJavaScriptBridge的时候需要首先判断一下WebViewJavaScriptBridge是否存在,如果不存在需要通过添加监听'WebViewJavascriptBridgeReady'来监听
//注册回调函数,第一次连接时调用 初始化函数 connectWebViewJavascriptBridge(function(bridge) { bridge.init(function(message, responseCallback) { bridgeLog('默认接收收到来自Java数据: ' + message); var responseData = '默认接收收到来自Java的数据,回传数据给你'; responseCallback(responseData); }); bridge.registerHandler("functionInJs", function(data, responseCallback) { bridgeLog('指定接收收到来自Java数据: ' + data); var responseData = '指定接收收到来自Java的数据,回传数据给你'; responseCallback(responseData); }); })
通过上面的链接WebViewJavascriptBridge可以得到一个可用WebViewJavascriptBridge,可以通过init方法来设置一个默认接收所以java发来的数据的回调,也可以通过registerHandler设置指定接收方法。
java发送数据给Js默认接收
mBridgeWebView.send("发送数据给web默认接收",new CallBackFunction(){ @Override public void onCallBack(String data) { Log.e(TAG, "来自web的回传数据:" + data); } });
java发送数据给Js指定方法接收
mBridgeWebView.callHandler("functionInJs","发送数据给web指定接收",new CallBackFunction(){ @Override public void onCallBack(String data) { Log.e(TAG, "来自web的回传数据:" + data); } });
5.)整个示例
为了方便学习,贴出整个示例
MainActivity
public class MainActivity extends AppCompatActivity {private static final String TAG=MainActivity.class.getSimpleName(); private BridgeWebView mBridgeWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); } private void initViews(){ mBridgeWebView= (BridgeWebView) findViewById( R.id.test_bridge_webView); mBridgeWebView.loadUrl("file:///android_asset/wx.html"); mBridgeWebView.setDefaultHandler(new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { Log.e(TAG, "DefaultHandler接收全部来自web的数据:"+data); function.onCallBack("DefaultHandler收到Web发来的数据,回传数据给你"); } }); //必须和js同名函数,注册具体执行函数,类似java实现类。 //第一参数是订阅的java本地函数名字 第二个参数是回调Handler , 参数返回js请求的resqustData,function.onCallBack()回调到js,调用function(responseData) mBridgeWebView.registerHandler("submitFromWeb", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { Log.e(TAG, "指定Handler接收来自web的数据:" + data); function.onCallBack("指定Handler收到Web发来的数据,回传数据给你"); } }); findViewById(R.id.to_web_default).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mBridgeWebView.send("发送数据给web默认接收",new CallBackFunction(){ @Override public void onCallBack(String data) { Log.e(TAG, "来自web的回传数据:" + data); } }); } }); findViewById(R.id.to_web).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mBridgeWebView.callHandler("functionInJs","发送数据给web指定接收",new CallBackFunction(){ @Override public void onCallBack(String data) { Log.e(TAG, "来自web的回传数据:" + data); } }); } }); }}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" tools:context="com.whoislcj.jsbridge.MainActivity"> <com.github.lzyzsd.jsbridge.BridgeWebView android:id="@+id/test_bridge_webView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <Button android:id="@+id/to_web_default" android:layout_margin="10dp" android:layout_width="match_parent" android:text="默认传递数据给Web" android:layout_height="wrap_content"/> <Button android:id="@+id/to_web" android:layout_margin="10dp" android:layout_width="match_parent" android:text="指定传递数据给Web" android:layout_height="wrap_content"/></LinearLayout>
wx.html
<html><head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <script > function testClick() { //发送消息给java代码 var data = '发送消息给java代码全局接收'; //第一个参数要发送的数据 第二个参数js在被回调后具体执行方法,responseData为java层回传数据 window.WebViewJavascriptBridge.send( data , function(responseData) { bridgeLog('来自Java的回传数据: ' +responseData); } ); } function testClick1() { //调用本地java方法 //第一个参数是 调用java的函数名字 第二个参数是要传递的数据 第三个参数js在被回调后具体执行方法,responseData为java层回传数据 var data='发送消息给java代码指定接收'; window.WebViewJavascriptBridge.callHandler( 'submitFromWeb' ,data , function(responseData) { bridgeLog('来自Java的回传数据: ' + responseData); } ); } function bridgeLog(logContent) { document.getElementById("log_msg").innerHTML = logContent; } //注册事件监听 function connectWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge) } else { document.addEventListener( 'WebViewJavascriptBridgeReady' , function() { callback(WebViewJavascriptBridge) }, false ); } } //注册回调函数,第一次连接时调用 初始化函数 connectWebViewJavascriptBridge(function(bridge) { bridge.init(function(message, responseCallback) { bridgeLog('默认接收收到来自Java数据: ' + message); var responseData = '默认接收收到来自Java的数据,回传数据给你'; responseCallback(responseData); }); bridge.registerHandler("functionInJs", function(data, responseCallback) { bridgeLog('指定接收收到来自Java数据: ' + data); var responseData = '指定接收收到来自Java的数据,回传数据给你'; responseCallback(responseData); }); }) </script></head><body><p>WebViewJsBridge</p><div> <button onClick="testClick()">发送数据给默认Handler接收</button></div><br/><div> <button onClick="testClick1()">发送数据给指定Handler接收</button></div><br/><div id="log_msg">调用打印信息</div></body></html>
- Android混合开发之WebViewJavascriptBridge实现JS与java安全交互
- Android混合开发之WebViewJavascriptBridge实现JS与java安全交互
- Android中WebViewJavascriptBridge实现JS与java安全交互
- iOS开发使用WebViewJavascriptBridge实现OC与JS交互
- Android 中利用WebViewJavascriptBridge 实现js和java的交互
- Android 利用WebViewJavascriptBridge 实现js和java的交互
- Android 利用WebViewJavascriptBridge 实现js和java的交互
- Android 中利用WebViewJavascriptBridge 实现js和java的交互
- Android 利用WebViewJavascriptBridge 实现js和java的交互
- Android 利用WebViewJavascriptBridge 实现js和java的交互
- 通过WebViewJavascriptBridge实现OC与JS交互
- 使用WebViewJavascriptBridge实现OC与JS交互
- 使用WebViewJavascriptBridge实现OC与JS交互
- Android混合开发之WebView与Js交互
- WebViewJavascriptBridge 实现js和java的交互
- OC与JS交互之WebViewJavascriptBridge
- OC与JS交互之WebViewJavascriptBridge
- Android混合开发 java和js交互
- JAVA利用字节流完成拷贝文件夹。
- 递归(汉诺塔)
- 动态内存分配
- 对一个人生日姓名进行操作(结构体)
- 页面背景-伪类选择器-相对定位-块和内联转换
- Android混合开发之WebViewJavascriptBridge实现JS与java安全交互
- 第一个用tikz画的图
- jvisualvm安装插件
- Unity3D 大型游戏 MOBA类手机游戏 状态机在游戏中的应用(18)
- Android端关于HTTPS的认证---->可用
- Struts2结合Bootstrap-Table分页的使用
- 深入理解c语言指针-第六章
- docker项目开发部署
- 二进制转十进制快速方法