Android 与 html5 的交互主要是两个部分, 与 HTML5 的交互以及与 JavaScript 的交互, 与 HTML5 的交互可以通过注册 onclick 事件转化为与 JavaScript 的交互
Android 与 JavaScript 的交互主要是通过相互调用方法实现的, Android 对 JavaScript 的可以称之为调用, 但是 JavaScript 对于 Android 代码的调用则是通过拦截 (@JavascriptInterface 与映射实现存在较多漏洞, 也不推荐使用)
Android 调用 JavaScript 代码有两种方式, 通过 webView 对象的 loadUrl(String) 或 evaluateJavascript(String, ValueCallback
- // audioPrepareResult 是当前页面中的一个 JavaScript 方法
- // startRecordResult 是 Android 本地方法返回的结果, 作为参数传递给 JavaScript 方法
- mWebView.evaluateJavascript("javascript:audioPrepareResult(\"" + startRecordResult + "\")", new ValueCallback<String>() {
- @Override
- public void onReceiveValue(String value) {
- // nothing
- }
- });
这里有一个坑, 如果 JavaScript 方法的参数是一个字符串的话, 一定要在参数前后手动加上 "(引号), 否则 JavaScript 会产生 undefined, 比较奇葩的是, 如果参数是一段 JSON, 所以就有了"{ \"longitude\": 0, \"latitude\": 0}" 这种代码
JavaScript 调用 Android 方法有三种, 第一种是通过 WebView 的 addJavascriptInterface(Object, String) 进行映射, 这个方法虽然很方便, 但是存在严重漏洞, 不推荐使用. 第二种方法是通过拦截 shouldOverrideUrlLoading(WebView, String) 进行 URL 拦截, 与约定匹配就进行对应的方法调用. 第三种是通过重写 WebChromeClient 里的 onJsAlert(WebView view, String url, String message, String defaultValue, JsPromptResult result), onJsConfirm(/* 参数同 onJsAlert/), onJsPrompt(/ 参数同 onJsAlert*/) 进行拦截对应的对话框, 匹配参数 3 的 message, 与约定匹配就执行对应的 Android 代码, 下面给出第三种代码的 demo:
- mWebView.setWebChromeClient(new WebChromeClient() {
- @Override
- public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
- Uri uri = Uri.parse(message);
- if (uri.getScheme().equals("CallAndroidMethod")) {
- switch (uri.getAuthority()) {
- case "recordAudio":
- boolean recordAudioResult = MainActivity.this.recordAudio();
- result.confirm(new Boolean(recordAudioResult).toString());
- return true;
- default:
- break;
- }
- }
- result.confirm(new Boolean(true).toString());
- return super.onJsPrompt(view, url, message, defaultValue, result);
- }
- });
调用这段代码对应的 H5 代码为:
- <html>
- <head>
- <meta charset="UTF-8" />
- <title>Android With H5 Demo</title>
- <script>
- function uploadImage() {
- var result = prompt("CallAndroidMethod://recordAudio?type=search");
- }
- </script>
- </head>
- <body>
- <button type="button" id="recordAudioButton" onclick="recordAudio()">Record Audio</button>
- </body>
- </html>
这里有个坑, 在 onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) 方法返回前一定要调用最后一个参数 JsPromptResult 的 confirm(bool) 方法, 否则会造成 HTML5 页面无响应
其他一些操作:
WebView 的 canGoBack() 与 goBack() 方法配合 Activity 的 onKeyDown(int keyCode, KeyEvent event) 可以实现用户按返回键是返回上一个 Web 页面而非退出页面
来源: http://www.bubuko.com/infodetail-2685987.html