WebView 与 JavaScript 的交互 Android 调用 JS&JS 调用 Android

35 篇文章 1 订阅
10 篇文章 0 订阅

https://www.jianshu.com/p/345f4d8a5cfa

WebView 与 JavaScript 的交互

Android 调用 JS

loadUrl()

JS 中的方法需要在 window 对象下

Vue 中可以参考

https://blog.csdn.net/maimiho/article/details/107708593

function callJS() {
  alert("Android调用了JS的callJS方法");
}
mWebView.loadUrl("javascript:callJS()");

注意事项:

JS 代码调用一定要在 WebViewClient#onPageFinished() 回调之后才能调用

evaluateJavascript()

mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String value) {
        //此处为 js 返回的结果
    }
});

JS 调用 Android

addJavascriptInterface()

  • 定义一个与 JS 对象映射关系的 Android 类:XXX.java
  • 定义 JS 需要调用的方法, 并加上 @JavascriptInterface 注解

MainActivity.java

//定义 JS 需要调用的方法, 并加上 @JavascriptInterface 注解
@JavascriptInterface
public void javaMethod(){
    System.out.println("JS调用了Android的hello方法");
}
//Android类对象映射到js的test对象
mWebView.addJavascriptInterface(MainActivity.this, "test");
function callAndroid() {
  // 由于对象映射,所以调用test对象等于调用Android映射的对象
  test.javaMethod("js调用了android中的hello方法");
}

shouldOverrideUrlLoading()

Android 通过 WebViewClient 的回调方法 shouldOverrideUrlLoading() 拦截 url

html 页面中点击 <a> 标签

或者修改 window.location (document.location)

function callAndroid() {
  /*约定的url协议为:js://webview?arg1=111&arg2=222*/
  document.location.href = "js://webview?arg1=111&arg2=222";
  //window.location.href = "js://"
}
mWebView.setWebViewClient(new WebViewClient() {
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
          // 步骤2:根据协议的参数,判断是否是所需要的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")) {
                  //  步骤3:
                  // 执行JS所需要调用的逻辑
                  System.out.println("js调用了Android的方法");
                  // 可以在协议上带有参数并传递到Android上
                  HashMap<String, String> params = new HashMap<>();
                  Set<String> collection = uri.getQueryParameterNames();
              }
              return true;
          }
          return super.shouldOverrideUrlLoading(view, url);
      }
  }
);

如果 JS 想要得到 Android 方法的返回值,只能通过 WebView 的 loadUrl() 去执行 JS 方法把返回值传递回去

mWebView.loadUrl("javascript:returnResult(" + result + ")");
function returnResult(result) {
  alert("result is" + result);
}

onJsAlert() onJsConfirm() onJsPrompt

常用的是拦截 JS 的输入框(即 prompt() 方法)

只有 prompt() 可以返回任意类型的值,操作最全面方便、更加灵活;而 alert() 对话框没有返回值;confirm() 对话框只能返回两种状态(确定 / 取消)两个值

function clickPrompt() {
  // 调用prompt()
  var result = prompt("js://demo?arg1=111&arg2=222");
  alert("demo " + result);
}
mWebView.setWebChromeClient(
        new WebChromeClient() {
            // 拦截输入框(原理同方式2)
            // 参数message:代表promt()的内容(不是url)
            // 参数result:代表输入框的返回值
            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
                // 根据协议的参数,判断是否是所需要的url(原理同方式2)
                // 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数)
                //假定传入进来的 url = "js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的)

                Uri uri = Uri.parse(message);
                // 如果url的协议 = 预先约定的 js 协议
                // 就解析往下解析参数
                if (uri.getScheme().equals("js")) {

                    // 如果 authority  = 预先约定协议里的 webview,即代表都符合约定的协议
                    // 所以拦截url,下面JS开始调用Android需要的方法
                    if (uri.getAuthority().equals("webview")) {

                        //
                        // 执行JS所需要调用的逻辑
                        System.out.println("js调用了Android的方法");
                        // 可以在协议上带有参数并传递到Android上
                        HashMap<String, String> params = new HashMap<>();
                        Set<String> collection = uri.getQueryParameterNames();

                        //参数result:代表消息框的返回值(输入值)
                        result.confirm("js调用了Android的方法成功啦");
                    }
                    return true;
                }
                return super.onJsPrompt(view, url, message, defaultValue, result);
            }

            // 通过alert()和confirm()拦截的原理相同,此处不作过多讲述

            // 拦截JS的警告框
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                return super.onJsAlert(view, url, message, result);
            }

            // 拦截JS的确认框
            @Override
            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
                return super.onJsConfirm(view, url, message, result);
            }
        }
);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值