WebView(二)—— WebView与JS交互方式

WebView与JS交互方式

1 Android调用JS方法

Android调用JS代码的方式有2种:

  • 通过WebViewloadUrl方法
  • 通过WebViewevaluateJavascript方法
1.1 通过WebViewloadUrl方法

将需要调用的JS代码以.html格式放到src/main/assets文件夹里,以下是javascript.html的代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Carson_Ho</title>
    <script>
       function callJS(){
          alert("Android调用了JS的callJS方法");
       }
    </script>
</head>
</html>

Android代码中通过WebView设置调用JS代码:

public class MainActivity extends AppCompatActivity {

    private WebView webView;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = findViewById(R.id.webView);
        button = findViewById(R.id.button);

        WebSettings webSettings = webView.getSettings();
        // 设置与JS交互的权限
        webSettings.setJavaScriptEnabled(true);
        // 设置允许JS弹窗
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webView.loadUrl("file:///android_asset/javascript.html");

        button.setOnClickListener(v -> {
            webView.post(() -> {
                // 调用javascript的callJS()方法
                webView.loadUrl("javascript:callJS()");
            });
        });

        // 由于设置了弹窗检验调用结果,所以需要支持js对话框
        // webview只是载体,内容的渲染需要使用webviewChromClient类去实现
        // 通过设置WebChromeClient对象处理JavaScript的对话框
        // 设置响应js的Alert()函数
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setTitle("Alert");
                builder.setMessage(message);
                builder.setPositiveButton(android.R.string.ok, (dialog, which) -> result.confirm());
                builder.setCancelable(false);
                builder.create().show();

                return true;
            }
        });
    } 
}

运行程序,点击按钮,如下所示:

android调用JS代码

需要注意的是,JS代码调用一定要在 onPageFinished方法回调之后才能调用,否则不会调用。onPageFinished()属于WebViewClient类的方法,主要在页面加载结束时调用。

1.2 通过WebViewevaluateJavascript方法

只需要将第一种方法的loadUrl方法替换成evaluateJavascript

button.setOnClickListener(v -> {
  webView.post(() -> {
    // 调用javascript的callJS()方法
    webView.evaluateJavascript("javascript:callJS()", value -> Log.e("CAH", value));
  });
});
1.3 比较

调用方式对比

两种方法可以混合使用,即Android 4.4以下使用laodUrl方法,Android 4.4以上使用evaluateJavascript方法:

button.setOnClickListener(v -> {
  webView.post(() -> {
    // 调用javascript的callJS()方法
    final int version = Build.VERSION.SDK_INT;
    if (version < 18) {
      webView.loadUrl("javascript:callJS()");
    } else {
      webView.evaluateJavascript("javascript:callJS()", value -> Log.e("CAH", value));
    }

  });
});

2 JS调用Android方法

  • 通过WebViewaddJavascriptInterface进行对象映射
  • 通过WebViewClientshouldOverrideUrlLoading方法回调拦截url
  • 通过WebChromeClientonJsAlert()onJsConfirm()onJsPrompt()方法回调拦截JS对话框alert()confirm()prompt() 消息
2.1 通过WebViewaddJavascriptInterface进行对象映射

步骤1:定义一个与JS对象映射关系的Android类:AndroidtoJS

public class AndroidJS extends Object {

    @JavascriptInterface
    public void hello(String msg) {
        System.out.println("JS调用了Android的hello方法");
    }
}

步骤2:将需要调用的JS代码以.html格式放到src/main/assets文件夹里:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Carson</title>
    <script>
      function callAndroid(){
        test.hello("js调用了android中的hello方法");
      }
    </script>
  </head>
  <body>
    <button type="button" id="button1" onclick="callAndroid()">点击调用Android代码</button>
  </body>
</html>

步骤3:在Android里通过WebView设置Android类与JS代码的映射:

public class MainActivity extends AppCompatActivity {

    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = findViewById(R.id.webView);

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true); // 设置与JS交互的权限

        // 通过addJavascriptInterface()将Java对象映射到JS对象
        // 参数1:Javascript对象名  参数2:Java对象名
        // AndroidJS类对象映射到js的test对象
        webView.addJavascriptInterface(new AndroidJS(), "test");

        webView.loadUrl("file:///android_asset/javascript.html");
    }

}
2.2 通过WebViewClientshouldOverrideUrlLoading方法回调拦截url

具体原理:

  1. Android通过 WebViewClient 的回调方法shouldOverrideUrlLoading ()拦截 url
  2. 解析该url的协议
  3. 如果检测到是预先约定好的协议,就调用相应方法

JS需要调用Android的方法

步骤1:在JS约定所需要的url协议:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Carson_Ho</title>
    <script>
      function callAndroid(){
        document.location = "js://webview?arg1=111&arg2=222";
      }
    </script>
  </head>
  <body>
    <button type="button" id="button" onclick="callAndroid()">点击调用Android代码</button>
  </body>
</html>

当该JS通过AndroidwebView.loadUrl("file:///android_asset/javascript.html")加载后,就会回调shouldOverrideUrlLoading()

步骤2:在Android通过WebViewClient复写shouldOverrideUrlLoading()

public class MainActivity extends AppCompatActivity {

  private WebView webView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    webView = findViewById(R.id.webView);

    WebSettings webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true); // 设置与JS交互的权限
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true); // 设置允许JS弹窗

    // 步骤1:加载JS代码
    webView.loadUrl("file:///android_asset/javascript.html");

    webView.setWebViewClient(new WebViewClient() {
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        // 步骤2:根据协议的参数,判断是否是所需的url
        // 一般根据scheme(协议格式)和authority(协议名)判断前两个参数
        // 假定传进来的 url="js://webview?arg1=111&arg2=222"
        Uri uri = Uri.parse(request.getUrl().toString());
        // 如果authority=预先约定协议里的webview,即代表符合约定的协议
        // 所以拦截url,下面JS开始调用Android需要的方法
        if (uri.getScheme().equals("js")) {
          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, request);
      }
    });
  }

}

如果JS想要得到Android方法的返回值,只能通WebViewloadUrl去执行JS方法把返回值传递回去, 相关的代码如下:

// MainActivity.java
mWebView.loadUrl("javascript:returnResult(" + result + ")");

// javascript.html
function returnResult(result){
    alert("result is" + result);
}
2.3 通过WebChromeClientonJsAlert()onJsConfirm()onJsPrompt()方法回调拦截JS对话框alert()confirm()prompt() 消息

JS中,有三个常用的对话框方法:

JS中常用的对护框

原理:Android通过WebChromeClientonJsAlert()onJsConfirm()onJsPrompt()方法回调分别拦截JS对话框
(即上述三个方法),得到它们的消息内容,然后解析即可。

经常用的拦截是:拦截JS的输入框(即prompt()方法)。因为只有prompt()可以返回任意类型的值,操作最全面方便、更加灵活;而alert()对话框没有返回值;confirm()对话框只能返回两种状态(确定 / 取消)两个值。

步骤1:加载JS代码,如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Carson_Ho</title>
    <script>
      function callAndroid(){
        var result=prompt("org://professor?arg1=111&arg2=222");
        alert("demo " + result);
      }
    </script>
  </head>

  <body>
    <button type="button" id="button1" onclick="callAndroid()">CallAndroid</button>
  </body>
</html>

当使用mWebView.loadUrl("file:///android_asset/javascript.html")加载了上述JS代码后,就会触发回调onJsPrompt(),具体如下:

  • 如果是拦截警告框(即alert()),则触发回调onJsAlert()
  • 如果是拦截确认框(即confirm()),则触发回调onJsConfirm()

步骤2:在Android通过WebChromeClient复写onJsPrompt():

public class MainActivity extends AppCompatActivity {

  private WebView webView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    webView = findViewById(R.id.webView);

    WebSettings webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true); // 设置与JS交互的权限
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true); // 设置允许JS弹窗

    // 步骤1:加载JS代码
    webView.loadUrl("file:///android_asset/javascript.html");

    webView.setWebChromeClient(new WebChromeClient() {

      // 拦截输入框
      // 参数 message:代表promt()的内容(不是url)result:代表输入框的返回值
      @Override
      public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        //通常根据scheme(协议格式) & authority(协议名)判断(前两个参数)
        Uri uri = Uri.parse(url);
        if (uri.getScheme().equals("org")) {
          if (uri.getAuthority().equals("professor")) {
            //参数result:表明消息框的返回值(输入值)
            result.confirm("js调用了Android的方法成功啦");
          }
          return true;
        }
        return super.onJsPrompt(view, url, message, defaultValue, result);
      }

      // 拦截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);
      }
    });
  }

}
2.4 三种方式的对比以及使用场景

三种方式对比

3 总结

总结

参考

https://blog.csdn.net/carson_ho/article/details/64904691

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 中,WebView 是一个内置的浏览器控件,可以加载网页并在应用程序中显示。WebViewJavaScript交互是常见的需求,主要有以下几种方式: 1. 通过 WebView 中的 loadUrl() 方法调用 JavaScript 函数。 可以使用 WebView 的 loadUrl() 方法加载一个包含 JavaScript 代码的 URL,实现与 JavaScript交互。例如,在 JavaScript 中定义一个函数: ```javascript function showToast(message) { alert(message); } ``` 然后在 Android 中使用 loadUrl() 方法调用这个函数: ```java webView.loadUrl("javascript:showToast('Hello World!')"); ``` 2. 在 WebView 中启用 JavaScript,并使用 addJavascriptInterface() 方法将 Java 对象注入到 JavaScript 中。 可以在 WebView 中启用 JavaScript 支持,并使用 addJavascriptInterface() 方法将 Java 对象注入到 JavaScript 中。这样,JavaScript 就可以调用 Java 对象的方法。例如,在 Java 中定义一个类: ```java public class MyJavaScriptInterface { private Context context; public MyJavaScriptInterface(Context context) { this.context = context; } @JavascriptInterface public void showToast(String message) { Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); } } ``` 然后在 WebView 中启用 JavaScript 支持,并将 MyJavaScriptInterface 对象注入到 JavaScript 中: ```java webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new MyJavaScriptInterface(this), "Android"); ``` 在 JavaScript 中就可以调用 MyJavaScriptInterface 对象的 showToast() 方法: ```javascript Android.showToast("Hello World!"); ``` 3. 使用 evaluateJavascript() 方法执行 JavaScript 代码并获取返回值。 可以使用 WebView 的 evaluateJavascript() 方法执行 JavaScript 代码,并通过回调函数获取返回值。例如,在 JavaScript 中定义一个函数: ```javascript function add(a, b) { return a + b; } ``` 然后在 Android 中使用 evaluateJavascript() 方法执行这个函数,并获取返回值: ```java webView.evaluateJavascript("add(1, 2)", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { // value = "3" } }); ``` 以上就是 WebViewJavaScript交互方式,开发者可以根据需求选择适合自己的方式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值