Android页面内嵌套h5页面已经是随处可见了。在Android原生页面和h5页面的取舍上那些不是本文的重点。重点是,如此多的页面用网页来写,那么必定涉及到网页与原生的交互,俗称js交互。
目标:h5页面点击按钮Android端接收到网页传给的json数据。
实现
网页端
网页端添加如下内容
<script type="text/javascript">
var hasBridge = false
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener('WebViewJavascriptBridgeReady', function () {
callback(WebViewJavascriptBridge)
}, false)
}
}
connectWebViewJavascriptBridge(function (bridge) {
bridge.init(function (message, responseCallback) {
hasBridge = true
var data = {'Javascript Responds': 'Wee!'}
$("#document .disabled").removeClass("disabled")
responseCallback(data)
})
$("#mzy").click(function(){
var sendObj = {"type":"user"};
sendObj["phone"] = "18067976937";
sendObj["nick"] = "maoamao";
bridge.send(JSON.stringify(sendObj), function (responseData) {
});
})
})
script>
其中 mzy 是定义的一个id = “mzy”的按钮。传递的json数据为
{
"type":"user",
"phone":"18067976937",
"nick":"maoamao",
}
Android端
Android端这里使用的github上开元项目BridgeWebView来显示h5页面。使用如下:
webview.setWebViewClient(new BridgeWebViewClient(webview) {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
view.loadData(errorHtml, "text/html; charset=UTF-8", null);
}
});
//JS交互
webview.setDefaultHandler(new DefaultHandler() {
@Override
public void handler(String data, CallBackFunction function) {
super.handler(data, function);
Log.e("data", "data = " + data);
try {
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create();
JSONObject jsonObject = new JSONObject(data);
String type = jsonObject.getString("type");
if (null != type && type.equals("user")) {
String nick = jsonObject.getString("nick");
Log.i("nick","nick = "+nick);
} else if (null != type && type.equals("XXXXXX")) {
xxxxxxxx;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
webview.loadUrl("XXXXXXXXXX");
webview.send("hello-javascript");
这里根据因为同一个页面可能会有多种不同的交互需求,所以这里用type来区分不同的交互类型。这里可以根据jsonObject.getString(“nick”)获取到nick字段。 webview.loadUrl(“XXXXXXXXXX”);设置成你自己的h5页面地址即可。
目标二:Android端传递参数给web页
上面代码块里面最后一句webview.send(“hello-javascript”);就是Android端发送了一个”hello-javascript”字符串给web页。
web页接收Android发来的参数
<script>
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener('WebViewJavascriptBridgeReady', function(){
callback(WebViewJavascriptBridge)
}, false)
}
}
connectWebViewJavascriptBridge(function (bridge) {
bridge.init(function (message, responseCallback) {
alert("message"+message)
var data = {'Javascript Responds': 'Wee!'}
new Vue({
el: "#vue-app",
template: "#app-template",
data:{
tab: 1,
},
events: {
'bridgeEvt': function(obj) {
bridge.send(JSON.stringify(obj),function(responseData){
console.log(responseData);
})
}
},
ready: function(){
if(/notice_type=2/.test(location.href)) {
this.tab = 2
}
},
});
responseCallback(data)
})
})
script>
其中alert(“message”+message)message就是从Android传过来的参数。我们可以进行处理。