感觉这一个比起上一个要写一个接口的方法更好,而且容易从JS获取参数,同时可以在Android里面调用获取到的参数;
代码
html
在src/main/下创建一个文件夹assets,里面添加一个javascript.html文件,内容如下;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>emperinter</title>
<script>
function callAndroid(){
<!-- 设置scheme(协议) & authority(协议名) -->
<!-- 这里的scheme为js & authority为webview-->
/*约定的url协议为:js://webview?arg1=111&arg2=222*/
/*传惨只要是 XXXX=YYYY即可,但我们一般用arg加数字来表示*/
document.location = "js://webview?arg1=lover&arg=emperinter&arg3=test&fuck=fuck";
}
</script>
</head>
<body>
<div align="center">
<!-- 点击按钮则调用callAndroid()方法 -->
<button style="font-size:55px;" type="button" id="button1" onclick="callAndroid()">点击调用Android代码</button>
</div>
</body>
</html>
布局
MainActivity
public class MainActivity extends AppCompatActivity {
WebView mwebview;
TextView mtext0;
TextView mtext1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mwebview = (WebView) findViewById(R.id.MainWeb);
mtext0 = (TextView) findViewById(R.id.Text0);
mtext1 = (TextView) findViewById(R.id.Text1);
WebSettings webSettings = mwebview.getSettings();
//设置与JS交互的权限
webSettings.setJavaScriptEnabled(true);
//设置允许JS弹窗
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
//Step1:load JS code
//格式规定为:file:///android_asset/文件名.html
mwebview.loadUrl("file:///android_asset/javascript.html");
//复写WebWiewClien类的shouldOverrideUrlLoading方法
mwebview.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//Step2:根据协议的参数,判断是否是所需要的url
//一般根据scheme(协议) & authority(协议名) 判断 (前两个参数)
//假定传进来的 url = "js://webview?arg1=111&arg2=222" (同时也是约定好的需要拦截的)
Uri uri = Uri.parse(url);
//如果url的协议 = 预先设定的 js 协议
//就往下解析参数
if(uri.getScheme().equals("js")){
//如果 authority = 预先约定协议里的webview,即代表都符合约定的协议
//所以拦截url,下面JS开始调用Android需要的方法
if(uri.getAuthority().equals("webview")){
//step3:
//执行JS所需要的调用的逻辑
System.out.println("Js调用了Andriod的方法!");
//可以在协议上带有参数并传递到Android上
//something wrong !
// HashMap<String,String> params = new HashMap<>();
// Set(String) collection = uri.getQuery();
Log.e("TAG", "JS 调用了 Android 的方法");
Set<String> collection = uri.getQueryParameterNames();
Iterator<String> it = collection.iterator();
// String result = "";
//// while (it.hasNext()) {
//// result += uri.getQueryParameter(it.next()) + ",";
//// }
//// Log.e("result:", result + "\n\n\n\n" );
String txt0 = uri.getQueryParameter(it.next());
String txt1 = uri.getQueryParameter(it.next());
Log.e("txt0:",txt0 + "\n\n\n");
mtext0.setText(txt0);
Log.e("txt1:",txt1 + "\n\n\n");
mtext1.setText(txt1);
// 测试传参
Log.e("test:",uri.getQueryParameter(it.next()));
Log.e("fuck:",uri.getQueryParameter(it.next()));
}
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
});
}
}
运行结果
更新
上面的的值是默认设置的,这下面的例子是人为从webview的输入框获取到的值;只需更改javascript.html即可;
- javascript.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>emperinter</title>
</head>
<body>
<div align="center">
<!-- 点击按钮则调用callAndroid()方法 -->
name:<input id="n">
<br/>
password:<input id="p">
<p>web测试是否获取到值了</p>
get_name:<p style="color:red;" id="gn">get_name</p>
get_password:<p style="color:red" id="gp">get_password</p>
<button style="font-size:32px;" type="button" id="button1" onclick="callAndroid()">点击调用Android代码</button>
</div>
<script>
function callAndroid(){
var name,password;
name = document.getElementById("n").value;
document.getElementById("gn").innerHTML = name;
password = document.getElementById("p").value;
document.getElementById("gp").innerHTML = password;
<!-- 设置scheme(协议) & authority(协议名) -->
<!-- 这里的scheme为js & authority为webview-->
/*约定的url协议为:js://webview?arg1=111&arg2=222*/
/*传惨只要是 XXXX=YYYY即可,但我们一般用arg加数字来表示*/
document.location = "js://webview?arg1=" + name + "&arg= " + password + "&arg3=test&fuck=fuck";
}
</script>
</body>
</html>
- 运行结果如图所示: