android与H5交互方法简介
https://blog.csdn.net/warmandfull/article/details/106728944
https://www.jianshu.com/p/97f52819a19d
http://www.manongjc.com/detail/20-dpggabmodgeqwmi.html
https://blog.csdn.net/yin_chenglong/article/details/80627318
https://github.com/17050097616/jsbridge-android
WebViewJavascriptBridgeDemo
https://github.com/CoderJackyHuang/WebViewJavascriptBridgeDemo
https://blog.csdn.net/weixin_40873000/article/details/78824930
https://blog.csdn.net/weixin_37730482/article/details/73468808
https://github.com/lzyzsd/JsBridge
WebViewJavascriptBridgeDemo 问题
https://blog.csdn.net/weixin_42081936/article/details/112198255
相册
https://github.com/runfengai/WebUploadImg
JAVA调用JS代码
方式一: 使用WebView的loadUrl()方法,以loadUrl(script)的方式调用。
方式二: 使用WebView的evaluateJavascript()方法。
JS调用JAVA代码
方式一: 使用WebView的addJavascriptInterface()方法注入对象。
方式二: 使用WebViewClient 的shouldOverrideUrlLoading()方法回调拦截请求。
方式三: 重写 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息。
test_java_call_js.html内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html" charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<!-- 用于显示JAVA调用JS的结果 -->
<center><p id="result"></p></center>
</body>
<script type="text/javascript">
//js无参方法
function javaCallJsNoParam(){
document.getElementById("result").innerHTML= 'JAVA调用JS成功!';
}
//js有参方法
function javaCallJsHaveParam(param){
document.getElementById("result").innerHTML= 'JAVA调用JS成功!,得到参数:'+param;
}
//js有返回值方法
function javaCallJsHaveReturn(){
var num = Math.random();
document.getElementById("result").innerHTML= 'JAVA调用JS成功!,返回随机数:'+num;
return 'js返回随机数'+num;
}
</script>
</html>
test_js_call_java.html内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html" charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<center>
<p><input type="button" value="JS调用JAVA无参方法" onclick="jsCallJavaNoParam()" /></p>
<p><input type="button" value="JS调用JAVA有参方法" onclick="jsCallJavaHaveParam()"/></p>
<p><input type="button" value="JS调用JAVA并获得返回结果" onclick="jsCallJavaHaveReturn()"/></p>
<p><input type="button" value="拦截URL测试" onclick="testShouldOverrideUrlLoading()"/></p>
<p><input type="button" value="测试onJsAlert" onclick="testOnJsAlert()"/></p>
<p><input type="button" value="测试onJsConfirm" onclick="testOnJsConfirm()"/></p>
<p><input type="button" value="测试onJsPrompt" onclick="testOnJsPrompt()"/></p>
</center>
</body>
<script type="text/javascript">
//调用java无参方法
function jsCallJavaNoParam(){
injectedObject.jsCallJavaNoParam();
}
//调用java有参方法
function jsCallJavaHaveParam(){
var num = Math.random();
injectedObject.jsCallJavaHaveParam(num+'');
}
//调用java有返回值方法
function jsCallJavaHaveReturn(){
var result = injectedObject.jsCallJavaHaveReturn();
alert('成功调用JAVA,返回结果为:'+result);
}
//测试拦截请求方式
function testShouldOverrideUrlLoading(){
document.location = 'http://testShouldOverrideUrlLoading.com';
}
//测试重写OnJsAlert()方法方式
function testOnJsAlert(){
var result = alert("测试onJsAlert");
}
//测试重写OnJsConfirm()方法方式
function testOnJsConfirm(){
confirm("测试onJsConfirm");
}
//测试重写OnJsPrompt()方法方式
function testOnJsPrompt(){
prompt("测试onJsPrompt");
}
</script>
</html>
MainActivity内容
public class MainActivity extends AppCompatActivity {
//webView
private WebView webView;
//“JAVA调用JS无参方法”
private Button btnJavaCallJSNoParamFunc;
//“JAVA调用JS有参方法”
private Button btnJavaCallJSHaveParamFunc;
//“JAVA调用JS并获得返回结果”
private Button btnJavaCallJSHaveReturnFunc;
//“跳转到html界面测试JS调用JAVA方法”
private Button btnToJSCallJavaFuncWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("demo");
setActivityMainToContentView();
}
/***
* 重写返回键响应方法
*/
@Override
public void onBackPressed() {
//找原来activity_main.xml中的元素
View v = findViewById(R.id.btn_to_js_call_java_func_webView);
//如果找不到,就设置ContentView为activity_main
if(v == null){
setActivityMainToContentView();
} else {
super.onBackPressed();
}
}
/***
* 设置ContentView为activity_main需要的一系列初始化
*/
private void setActivityMainToContentView() {
setContentView(R.layout.activity_main);
//初始webView
initWebView();
btnJavaCallJSNoParamFunc = findViewById(R.id.btn_java_call_js_no_param_func);
btnJavaCallJSNoParamFunc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callJs("javascript:javaCallJsNoParam()");
//webView.loadUrl("javascript:javaCallJsNoParam()");
}
});
btnJavaCallJSHaveParamFunc = findViewById(R.id.btn_java_call_js_have_param_func);
btnJavaCallJSHaveParamFunc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callJs("javascript:javaCallJsHaveParam('"+ +Math.random() +"')");
}
});
btnJavaCallJSHaveReturnFunc = findViewById(R.id.btn_java_call_js_have_param_return_func_);
btnJavaCallJSHaveReturnFunc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callJs("javascript:javaCallJsHaveReturn()");
}
});
btnToJSCallJavaFuncWebView = findViewById(R.id.btn_to_js_call_java_func_webView);
btnToJSCallJavaFuncWebView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//加载test_js_call_java.html
webView.loadUrl("file:///android_asset/test_js_call_java.html");
//设置ContentView为webView;
setContentView(webView);
}
});
}
private void initWebView() {
webView = new WebView(this);
WebSettings webSettings = webView.getSettings();
//设置支持javaScript脚步语言
webSettings.setJavaScriptEnabled(true);
//限制在WebView中打开网页,而不用默认浏览器
//在这里我重写了WebViewClient中的shouldOverrideUrlLoading方法,来验证安卓拦截url
//webView.setWebViewClient(new WebViewClient());
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Uri uri = request.getUrl();
Toast.makeText(MainActivity.this, "拦截到URL:"+uri.toString(), Toast.LENGTH_SHORT).show();
//返回true取消当前加载,否则返回false.
return true;
}
}
);
//设置可让界面弹出alert等提示框
//webView.setWebChromeClient(new WebChromeClient());
webView.setWebChromeClient(new WebChromeClient(){
//重写onJsAlert方法,做出简单响应
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//只对特殊信息做出响应,避免影响其他警告框
if(message.equals("测试onJsAlert")){
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
}
return super.onJsAlert(view, url, message, result);
}
//重写onJsConfirm方法,做出简单响应
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
return super.onJsConfirm(view, url, message, result);
}
//重写onJsPrompt方法,做出简单响应
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
return super.onJsPrompt(view, url, message, defaultValue, result);
}
});
//设置支持js调用java
webView.addJavascriptInterface(new JsObject(),"injectedObject");
//加载网络资源
webView.loadUrl("file:///android_asset/test_java_call_js.html");
}
/***
* 被注入对象
*/
class JsObject {
//能够被JS调用的无参方法
@JavascriptInterface
public void jsCallJavaNoParam() {
Toast.makeText(MainActivity.this, "JS成功调用JAVA!", Toast.LENGTH_SHORT).show();
}
//能够被JS调用的有参方法
@JavascriptInterface
public void jsCallJavaHaveParam(String param) {
Toast.makeText(MainActivity.this, "JS成功调用JAVA有参方法!参数为:"+param, Toast.LENGTH_SHORT).show();
}
//能够被JS调用的带返回值的方法
@JavascriptInterface
public String jsCallJavaHaveReturn() {
Double num = Math.random();
return ""+num;
}
}
/***
* 调用JS
*/
private void callJs(String javascript){
//调用JS
webView.evaluateJavascript(javascript, new ValueCallback<String>() {
@Override
public void onReceiveValue(String response) {
//如果有返回值,做出简单响应(JS函数无返回值是,response不为null,而是字符串"null")
if(!response.equals("null")) {
Toast.makeText(MainActivity.this, "JS返回的随机数的值为" + response, Toast.LENGTH_SHORT).show();
}
}
});
//设置ContentView为webView;
setContentView(webView);
}
}