项目接下来的任务中可能会需要H5与Android交互,用本篇文章记录一下JS交互的实现方案。
用于测试的Hmtl如下:
//Html文件,放在项目中的assets文件夹下
<!DOCTYPE html>
<html lang=zh-CN>
<head>
<meta charset=utf-8>
<title>test</title>
<script>
function callAndroid(){
JsInterface.jsCallAndroid('JS测试参数');
}
function androidCall(params){
document.getElementById("div_text").innerHTML = 'receiver js call , param is '+params;
return 'JS返回参数';
}
</script>
</head>
<body>
<div id="div_text" style="width:800px;height:120px;font-size:24px"></div>
<button type="button" style="width:240px;height:88px;font-size:24px" onclick="callAndroid()">
test_call_android
</button>
</body>
</html>
JS交互分为JS调用Android和Android调用JS,下面分别介绍一下。
JS调用Android
JS调用安卓有三种方法,分别是:
- 向WebView添加JavascriptInterface。
- 设置WebView的WebViewClent,通过重写shouldOverrideUrlLoading()方法进行处理。
- 设置WebView的WebViewChromeClient,通过重写onJsAlert()、onJsConfirm()、onJsPrompt()其中一个方法进行处理。
方法2、3需要前后端制定相应的协议,解析url或者message后根据协议进行处理,比较复杂。所以我个人更倾向于使用方法1。
实现代码如下:
//接口类
public class JsInterface {
@JavascriptInterface
public void jsCallAndroid(String params) {
}
}
@SuppressLint("SetJavaScriptEnabled")
public class WebViewActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_web_view_activity);
findViewById(R.id.tv_back).setOnClickListener(v -> finish());
WebView webView = findViewById(R.id.web_view);
//方法1
//启用JavaScript
webView.getSettings().setJavaScriptEnabled(true);
//向webView添加JavascriptInterface
webView.addJavascriptInterface(new JsInterface(), "JsInterface");
//方法2
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
try {
String decodeUrl = URLDecoder.decode(request.getUrl().toString(), StandardCharsets.UTF_8.toString());
//根据解析decodeUrl中的内容来进行响应的处理,这里不做演示。
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return super.shouldOverrideUrlLoading(view, request);
}
});
//方法3
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//解析url或者message中的内容来进行响应的处理,这里不做演示。
return super.onJsAlert(view, url, message, result);
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
//解析url或者message中的内容来进行响应的处理,这里不做演示。
return super.onJsConfirm(view, url, message, result);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
//解析url或者message中的内容来进行响应的处理,这里不做演示。
return super.onJsPrompt(view, url, message, defaultValue, result);
}
});
webView.loadUrl("file:///android_asset/index.html");
}
}
Android调用JS
Android调用JS有两种方法,分别是:
- WebView.loadUrl()
- WebView.evaluateJavascript(),此方法在Android 4.4以上才能使用。
由于WebView.evaluateJavascript()在android4.4以上才可以使用,因此可以采用两者结合的方式,代码如下:
public class WebViewActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_web_view_activity);
webView = findViewById(R.id.web_view);
findViewById(R.id.tv_call_js).setOnClickListener(v -> {
String params = "Android测试参数";
String loadUrl = "javascript:androidCall('" + params + "')";
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
//此方法没有返回值
webView.loadUrl(loadUrl);
} else {
//此方法可以获取到JS的返回值
webView.evaluateJavascript(loadUrl, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
tv_result1.setText("receiver js return , value is " + value);
}
});
}
});
}
}
效果图
测试效果如下图: