@Tyhj
2019-03-11T16:09:05.000000Z
字数 3899
阅读 2019
Android
其实我觉得原生的方法也还是比较简单的,具体使用可以看Android WebView与JavaScript的交互;JsBridge应该就是简单的封装了一下,让调用更加简单一些吧;
JSBridge是一座用JavaScript搭建起来的桥,一端是web,一端是native。我们搭建这座桥的目的也很简单,让native可以调用web的js代码,让web可以 “调用” 原生的代码
使用JsBridge需要使用BridgeWebView
控件,其实这个控件就是重写了WebView,在WebView初始化的时候注入了一些JavaScript,便于我们之后的使用
webView = findViewById(R.id.bridgeWebView);
//加载本地HTML文件
webView.loadUrl("file:///android_asset/test2.html");
HTML代码,放在assets文件下的HTML,test()
方法暂时没有实现,里面我写了一个类似Toast的方法,来展示数据
<html>
<head>
<title>js调用android原生代码</title>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<meta id="viewport" name="viewport"
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,minimal-ui">
</head>
<body>
<br/>
<li><a onclick="test()">点击调用Android的方法</a></li>
<br/>
</body>
</html>
<script>
<!--一个类似Toast的JavaScript方法,不用管怎么搞的-->
function toast(msg,duration){
duration=isNaN(duration)?3000:duration;
var m = document.createElement('div');
m.innerHTML = msg;
m.style.cssText="width: 60%;min-width: 150px;opacity: 0.7;height: 30px;color: rgb(255, 255, 255);line-height: 30px;text-align: center;border-radius: 5px;position: fixed;top: 40%;left: 20%;z-index: 999999;background: rgb(0, 0, 0);font-size: 12px;";
document.body.appendChild(m);
setTimeout(function() {
var d = 0.5;
m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
m.style.opacity = '0';
setTimeout(function() { document.body.removeChild(m) }, d * 1000);
}, duration);
}
</script>
Java中使用下面这个方法就可以暴露方法给JavaScript,方法名为submitFromWeb
,data
为JavaScript传进来的数据,通过function.onCallBack()
方法返回数据给JavaScript
//注册方法供JavaScript调用
webView.registerHandler("submitFromWeb", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
Toast.makeText(JsBridgeActivity.this, "从JavaScript接收到的数据为:" + data, Toast.LENGTH_SHORT).show();
//返回数据给JavaScript
function.onCallBack("Hello from Android");
}
});
使用test()方法,JavaScript中调用这个方法并传入数据进来,这里对返回的数据responseData
进行展示
<li><a onclick="test()">点击调用Android的方法</a></li>
<script>
function test(){
WebViewJavascriptBridge.callHandler(
'submitFromWeb'
, {'data': 'Hello form JavaScript'}
, function(responseData) {
toast(responseData)
}
);
}
</script>
库也提供了一个简单的没有回调的调用方式:
webView.setDefaultHandler(new DefaultHandler());
Js调用的时候也可以不指定方法名:
<script>
function test2(){
window.WebViewJavascriptBridge.send(
{'data': 'Hello form JavaScript default'}
, function(responseData) {
toast(responseData)
});
}
</script>
看了DefaultHandler
的源码,暂时没想到有什么用,除非自己重写handler
方法,和第一个用法相比的确是少了一个方法名
public class DefaultHandler implements BridgeHandler{
String TAG = "DefaultHandler";
@Override
public void handler(String data, CallBackFunction function) {
if(function != null){
function.onCallBack("DefaultHandler response data");
}
}
}
这个东西看起来和JavaScript调用Android是差不多的,先在JavaScript中注册方法供Android调用,这个脚本放在标签后面就行了,为什么看起来这么复杂呢,因为必须先检测WebViewJavascriptBridge是否存在
<script>
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
callback(WebViewJavascriptBridge)
},
false
);
}
}
connectWebViewJavascriptBridge(function(bridge) {
bridge.registerHandler("functionInJs", function(data, responseCallback) {
document.getElementById("show").innerHTML = ("data from Java: = " + data);
if (responseCallback) {
var responseData = "Javascript Says Right back aka!";
responseCallback(responseData);
}
});
})
</script>
接下来在Android中调用就好了
webView.callHandler("functionInJs", "执行JavaScript方法", new CallBackFunction() {
@Override
public void onCallBack(String data) {
Toast.makeText(JsBridgeActivity.this, data, Toast.LENGTH_SHORT).show();
}
});
这其中有一个大坑,我手机是Android 9.0的,我下载了dome完全没问题,然后我按照demo方法在我的代码里面写,发现怎么搞都不行,JavaScript方法没有被调用,直到完全改成和demo一样,还是不行,我又改了gradle里面的各种配置,还是不行,最后我把依赖删除了,集成demo里面的那个library,然后好了
repositories {
// ...
maven { url "https://jitpack.io" }
}
dependencies {
compile 'com.github.lzyzsd:jsbridge:1.0.4'
}
JsBridge的最后一个版本1.0.4(3年前的版本)是有问题的;这个项目在github上有100多个问题,最后代码一次提交是6个月前,感觉不是很靠谱,看的出来大家都是Fork下来自己修改的;