一、Android原生控件调用H5的JS方法实现参数互传
点击Android原生控件,H5获取Android传递过来的参数
H5代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Android与H5交互</title>
<script>
// Android需要调用的方法
function Android2JS(json){
document.getElementById("android2Js").innerHTML =json;
}
</script>
</head>
<body>
<button id="android2Js">准备接收Android传过来的参数</button>
</body>
</html>
android实现方法
WebView基本设置:
WebSettings webSettings = mWebView.getSettings();
// 设置与Js交互的权限
webSettings.setJavaScriptEnabled(true);
// 设置允许JS弹窗
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
//H5对应的地址,也可载入本地H5代码,格式规定为:file:///android_asset/android2h5.html
mWebView.loadUrl("http://192.168.0.115:9999/linxz-user/jsp/android2h5.html");
// 由于设置了弹窗检验调用结果,所以需要支持js对话框
// webview只是载体,内容的渲染需要使用webviewChromClient类去实现
// 通过设置WebChromeClient对象处理JavaScript的对话框
//设置响应js 的Alert()函数
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
return true;
}
});
*方法1:*
// 必须另开线程进行JS方法调用(否则无法调用)
mWebView.post(new Runnable() {
@Override
public void run() {
// 注意调用的JS方法名要对应上
// 调用javascript的Android2JS(json)方法
mWebView.loadUrl("javascript:Android2JS('goodsId1234')");
}
方法2:
api = Build.VERSION_CODES.KITKAT版本以上才能使用
mWebView.evaluateJavascript("javascript:Android2JS('goodsId1234')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
}
});
效果如下:未点击JS接收ANDROID传递过来的参数之前:
点击了之后:
H5获取到了Android传递过来的“goodsId1234”,并修改了按钮的值
点击Android原生控件,从H5的JS方法中获取到想要的参数
H5代码:跟上面的一样,多了一个返回值,如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Android与H5交互</title>
<script>
// Android需要调用的方法
function Android2JS(json){
document.getElementById("android2Js").innerHTML=json;
return "活动id:123";
}
</script>
</head>
<body>
<button id="android2Js">准备接收Android传过来的参数</button>
</body>
</html>
android实现代码,使用上面的第二种方法,如下:
// 只需要将第一种方法的loadUrl()换成下面该方法即可
mWebView.evaluateJavascript("javascript:Android2JS('goodsId1234')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
btnJS2Android.setText(""+value);
}
});
结果:android获取到了H5上面的JS方法的返回值“活动id:123”,如下:
随便说一下,H5返回来的明明是“活动id:123”,但是到了手机上就成了“活动ID:123”,有毒么…
Button小写自动变大写
二、H5调用Android定义的JS方法,实现参数的互传
点击H5的控件,将H5对应的参数传给Android
H5代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML调用android</title>
<script>
function js2Android(){
// 由于对象映射,所以调用androidFlag对象等于调用Android映射的对象
androidFlag.buyGoods("goodsId123");
}
</script>
</head>
<body>
<button type="button" id="button1" onclick="js2Android()">HTML调用Android定义的JS代码</button>
</body>
</html>
Android端代码:
编写一个类继承Object,在该类里编写对应的JS方法
class Android2JS extends Object{
// 定义JS需要调用的方法
// 被JS调用的方法必须加入@JavascriptInterface注解
@JavascriptInterface
public void buyGoods(String goodsId) {
btnJS2Android.setText("JS点击了这个商品:"+goodsId);
}
}
WebView配置,在上面配置的基础上添加如下配置:
// 通过addJavascriptInterface()将Java对象映射到JS对象
//参数1:Javascript对象名
//参数2:Java对象名
mWebView.addJavascriptInterface(new Android2JS(), "androidFlag");//Android2JS类对象映射到js的androidFlag对象
注意:androidFlag这个标识与上门H5的androidFlag要一致
结果:点击了H5上的“HTML调用Android定义的JS代码”后,Android获取到了对应的参数“goodsId123”。
效果如下:
点击了之后:
以上方法存在漏洞,并且好像对应IOS不适用,所以很多是根据拦截URL地址进行参数传递。定义一套专用的地址协议,用于客户端拦截。方法如下。
H5代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Carson_Ho</title>
<script>
function js2Android(){
/*约定的url协议为:lianjiu://webview?goodsId=111&consignorId=222*/
document.location = "lianjiu://webview?goodsId=111&consignorId=222";
}
</script>
</head>
<body>
<button type="button" id="button1" onclick="js2Android()">点击购买通知Android进去商品详情页面</button>
</body>
</html>
Android代码:
重写WebViewClient方法,
// 复写WebViewClient类的shouldOverrideUrlLoading方法
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 步骤2:根据协议的参数,判断是否是所需要的url
// 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数)
//假定传入进来的约定的url协议为:lianjiu://webview?goodsId=111&consignorId=222(同时也是约定好的需要拦截的)
Uri uri = Uri.parse(url);
// 如果url的协议 = 预先约定的 js 协议
// 就解析往下解析参数
if (uri.getScheme().equals("lianjiu")) {
// 如果 authority = 预先约定协议里的 webview,即代表都符合约定的协议
// 所以拦截url,下面JS开始调用Android需要的方法
if (uri.getAuthority().equals("webview")) {
// 步骤3:
// 执行JS所需要调用的逻辑
// 可以在协议上带有参数并传递到Android上
HashMap<String, String> params = new HashMap<>();
Set<String> collection = uri.getQueryParameterNames();
String goodsId = uri.getQueryParameter("goodsId");
String consignorId = uri.getQueryParameter("consignorId");
btnJS2Android.setText("商品Id为:" + goodsId + "---商家的Id为:" + consignorId);
}
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
}
);
结果:点击购买商品后,Android获取到对应的商品id跟商家id
点击之后: