android 和H5 交互,html调用android的方法
目前我这边需求是 android 里面嵌套了h5的界面,然后我这边要提供方法,让h5里面调。
1.模拟h5的界面:
定义一个 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>
把html放到assets下面:
2.android activity里面下一个webview布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Activity 代码:
public class WebViewActivity extends AppCompatActivity {
private WebView mWv;
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview_module);
context = this;
mWv = findViewById(R.id.webview);
initWebView();
}
private void initWebView() {
WebSettings _setting = mWv.getSettings();
_setting.setSupportZoom(true);//支持缩放
_setting.setBuiltInZoomControls(true);//设置出现缩放工具
_setting.setUseWideViewPort(true);//适应分辨率
_setting.setJavaScriptEnabled(true);//设置能够解析Javascript
_setting.setDomStorageEnabled(true);
mWv.addJavascriptInterface(new JsObject(context), "injectedObject");
//设置允许webview访问外部文件,android 11 上的问题
_setting.setAllowFileAccess(true);
_setting.setAllowContentAccess(true);
_setting.setLoadWithOverviewMode(true);
_setting.setCacheMode(WebSettings.LOAD_NO_CACHE);
mWv.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
});
mWv.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Log.i("wuden", "message:" + consoleMessage.message());
return super.onConsoleMessage(consoleMessage);
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}
});
//h5 调用java方法
String path = "file:///android_asset/test_js_call_java.html";
mWv.loadUrl(path);
}
}
方法简介
public void addJavascriptInterface (Object object, String name)
将提供的Java对象注入到此WebView中。使用提供的名称将对象注入到网页的所有框架中,包括所有iframes。这允许从JavaScript访问Java对象的方法。对于以APIBuild.VERSION_CODES.JELLY_bean_MR1和更高版本为目标的应用程序,只有带有JavascriptInterface注释的公共方法才能从JavaScript访问。对于针对API Build.VERSION_CODES.JELLY_bean或更低的应用程序,可以访问所有公共方法(包括继承的方法),注意,注入的对象将在JavaScript中出现,直到下一个加载页面(Re)为止。应该在注入对象之前启用JavaScript。例如:
class JsObject {
@JavascriptInterface
public String toString() { return "injectedObject"; }
}
webview.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsObject(), "injectedObject");
webView.loadData("", "text/html", null);
webView.loadUrl("javascript:alert(injectedObject.toString())");
新建了一个JsObject类:
里面放到:
/***
* 被注入对象
*/
class JsObject {
//能够被JS调用的无参方法
@JavascriptInterface
public void jsCallJavaNoParam() {
Toast.makeText(WebViewActivity.this, "JS成功调用JAVA!", Toast.LENGTH_SHORT).show();
}
//能够被JS调用的有参方法
@JavascriptInterface
public void jsCallJavaHaveParam(String param) {
Toast.makeText(WebViewActivity.this, "JS成功调用JAVA有参方法!参数为:"+param, Toast.LENGTH_SHORT).show();
}
//能够被JS调用的带返回值的方法
@JavascriptInterface
public String jsCallJavaHaveReturn() {
Double num = Math.random();
return ""+num;
}
}
然后html里面 去调用android的方法:
代码链接:https://blog.csdn.net/warmandfull/article/details/106728944
写的很不错,我自己试了下,然后又整理的。