近期在做一个项目,使用的是Native+H5的方式实现的。众所周知的是在Android中,Webview所实现的java与js的交互存在一些安全问题,并且这样的使用方式,没法让一套H5同时适配Android和iOS两个平台,因此,就需要有一个中间组件来实现js与本地的代码的交互,也就是JsBridg
这里介绍下JsBridge第三方库的使用。
github传送门:https://github.com/lzyzsd/JsBridge
效果图如下:
使用作者推荐方式
1.首先在工程根目录的 build.gradle 文件中加入: maven { url "https://jitpack.io" }
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
}
2.在要module 的 build.gradle 中加入 :implementation 'com.github.lzyzsd:jsbridge:1.0.4'
implementation 'com.github.lzyzsd:jsbridge:1.0.4'
然后同步一下代码
3.测试用的html文件 demo.html 放在 assets 中 :
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<title>
js调用java
</title>
</head>
<body>
<p>
<div id="init">
</div>
</p>
<p>
<xmp id="show">
</xmp>
</p>
<p>
<input type="text" id="text1" value="admin" />
</p>
<p>
<input type="text" id="text2" value="password" />
</p>
<p>
<input type="button" id="enter" value="DefaultHandler方式" onclick="testClick();"
/>
</p>
<p>
<input type="button" id="enter1" value="调用submitFromWeb方法" onclick="testClick1();"
/>
</p>
<p>
<input type="button" id="enter2" value="显示html" onclick="testDiv();" />
</p>
<p>
<input type="file" value="打开文件" onclick="onOpen();"/>
</p>
</body>
<script>
function testDiv() {
document.getElementById("show").innerHTML = document.getElementsByTagName("html")[0].innerHTML;
}
/*用来展示默认方式*/
function testClick() {
var str1 = document.getElementById("text1").value;
var str2 = document.getElementById("text2").value;
//send message to native
var data = {id: 1, content: "我是内容哦"};
//===3===调原生
window.WebViewJavascriptBridge.send(
data
, function(responseData) {
//java中DefaultHandler所实现的方法中callback所定义的入参:responseData
document.getElementById("show").innerHTML = "data = " + responseData
}
);
}
function testClick1() {
var str1 = document.getElementById("text1").value;
var str2 = document.getElementById("text2").value;
//===4===调原生方法submitFromWeb
window.WebViewJavascriptBridge.callHandler(
'submitFromWeb'
, {'Data': 'json数据传给Android端'} //该类型是任意类型
, function(responseData) {
document.getElementById("show").innerHTML = "得到Java传过来的数据 data = " + responseData
}
);
}
function onOpen() {
var str1 = document.getElementById("text1").value;
var str2 = document.getElementById("text2").value;
var data = "name=" + str1 + ",pass=" + str2;
//===5===调原生方法functionOpen
window.WebViewJavascriptBridge.callHandler(
'functionOpen'
, data
, function(responseData) {
//document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData;
}
);
}
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
callback(WebViewJavascriptBridge)
},
false
);
}
}
connectWebViewJavascriptBridge(function(bridge) {
//===1===在JS中注册默认的Handler,以方便Java调用,java通过send方法发送数据
bridge.init(function(message, responseCallback) {
console.log('JS got a message', message);
var data = {
'json': 'JS返回任意数据!'
};
console.log('JS responding with', data);/*打印信息*/
document.getElementById("init").innerHTML = "data = " + message;
responseCallback(data);
});
//===2===注册functionJs方法供java调用
bridge.registerHandler("functionJs", function(data, responseCallback) {
document.getElementById("show").innerHTML = ("Android端: = " + data);
var responseData = "Javascript 数据";
responseCallback(responseData);
});
})
</script>
</html>
5.在布局文件中使用:
<com.github.lzyzsd.jsbridge.BridgeWebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</com.github.lzyzsd.jsbridge.BridgeWebView>
使用JsBridge库
1.提供操作给Js调用
java中的注册的监听代码:
//注册submitFromWeb方法,供js调用
bridgeWebView.registerHandler("submitFromWeb", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
Log.i(TAG, "得到JS传过来的数据 data =" + data);
show(data);
function.onCallBack("传递数据给JS");
}
});
Js如果需要调用Java提供的这个方法的时候,则需要调用这个Handler,而在java中注册时参数submitFromWeb
将作为Js调用时使用的Key值。
js中调用的代码方式如下:
window.WebViewJavascriptBridge.callHandler(
'submitFromWeb'
, {'Data': 'json数据传给Android端'} //该类型是任意类型
, function(responseData) {
document.getElementById("show").innerHTML = "得到Java传过来的数据 data = " + responseData
}
)
另外:库也提供了一个简单的没有回调的调用方式:
java中的监听代码:
webView.setDefaultHandler(new DefaultHandler());
Js中的调用方式为:
window.WebViewJavascriptBridge.send(
data
, function(responseData) {
//java中DefaultHandler所实现的方法中callback所定义的入参:responseData
document.getElementById("show").innerHTML = "data = " + responseData
}
)
2.提供操作给Java调用 :
js中注册监听代码:
bridge.registerHandler("functionJs", function(data, responseCallback) {
document.getElementById("show").innerHTML = ("Android端: = " + data);
var responseData = "Javascript 数据";
responseCallback(responseData);
});
Java中调用方式为:
bridgeWebView.callHandler("functionJs", new Gson().toJson(user), new CallBackFunction() {
@Override
public void onCallBack(String data) {
Toast.makeText(MainActivity.this, "默认执行数据:" + data, Toast.LENGTH_LONG).show();
}
});
注意:同样的,在JS中也可以注册默认的Handler,以方便Java调用,java通过send方法发送数据
js中注册默认的监听事件:
bridge.init(function(message, responseCallback) {
console.log('JS got a message', message);
var data = {
'json': 'JS返回任意数据!'
};
console.log('JS responding with', data);/*打印信息*/
document.getElementById("init").innerHTML = "data = " + message;
responseCallback(data);
})
java中调用send方法:
bridgeWebView.send("不接受返回值");
bridgeWebView.send("接受返回值", new CallBackFunction() {
@Override
public void onCallBack(String data) {
show(data);
}
});
代码稍微有点多,就不一一展示了
至此,jsBridge的使用流程介绍完毕。