我是靠谱客的博主 痴情钥匙,最近开发中收集的这篇文章主要介绍Web与JS交互,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Android通过WebView与JS交互
Android调用JS
JS调用android

一、Android通过WebView与JS交互

1.1、android通过WebView调用js代码方法有2中:

  1. 通过WebView的loadUrl()
  2. 通过WebView的evaluateJavascript()

1.2、JS通过WebView调用android代码的方式有3中:

  1. 通过WebView的addJavascriptInterface()进行对象映射
  2. 通过WebViewClient的shouldOverrideUrlLoading()方法拦截url
  3. 通过WebChromeClient的onJsAlert(), onJsConfirm(), onJsPrompt()方法回调拦截JS对话框的alert()、confirm()、prompt()消息

二、具体使用:

2.1android通过WebView调用js代码方法

2.1.1通过WebView的loadUrl()

实例介绍:点击Android中的按钮,即调用WebView的JS中的callJS()方法
具体使用:

  1. 为了方便展示,在src/main/assets文件夹下创建html文件,加载html文件mWebView.loadUrl(file:///android_asset/demo.html)
<html>
<head>
    <title>demo</title>
    <script>
        function callJS(){
        alert("Android 调用了js");
        }
    </script>
</head>
</html>
  1. Android调用js的代码:
public class WebViewJsActivity extends Activity implements View.OnClickListener {
    private WebView mWebView;
    private Button mLoadUrlBt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view_js);
        mLoadUrlBt = findViewById(R.id.load_url);
        mLoadUrlBt.setOnClickListener(this);
        mWebView = findViewById(R.id.webview_js);
        WebSettings settings = mWebView.getSettings();
        //加载js代码
        settings.setJavaScriptEnabled(true);
        mWebView.loadUrl("file:///android_asset/demo.html");
        //因为在js中用到了alert(),因此需要设置WebChromeClient()
        mWebView.setWebChromeClient(new WebChromeClient());
    }

    //通过loadurl调用js方法
    private void loadUrlToJS(){
       // 注意调用的JS方法名要对应上
       // 调用javascript的callJS()方法
        mWebView.loadUrl("javascript:callJS()");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.load_url:
                loadUrlToJS();
                break;
                
            }
    }
}

特别注意:JS代码调用一定要在 onPageFinished() 回调之后才能调用,否则不会调用。

onPageFinished()属于WebViewClient类的方法,主要在页面加载结束时调用

2.1.2通过WebView的evaluateJavascript()

  • 优点:该方法比第一种方法效率更高、使用更简洁。
  1. 该方法的执行不会使页面刷新,loadUrl则会
  2. Android4.4后才可以使用
  • 具体使用
    //通过evaluateJavascript与js交互
    private void evaluateJavascript(){
        mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
            //value为js返回的结果

            }
        });
    }

建议两种方式混合使用,在android4.4以下用loadUrl,在Android4.4以上用evaluateJavascript()

 if(Build.VERSION.SDK_INT  < Build.VERSION_CODES.KITKAT){
            mWebView.loadUrl("javascript:callJS()");
        }else {
            mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String value) {
                    
                }
            });

        }

2.2JS通过WebView调用Android代码

2.2.1通过WebView的addJavascriptInterface()进行对象映射

  1. 定义一个与JS对象映射关系的Android类 MyObject
  class MyObject{
        // 定义JS需要调用的方法
        // 被JS调用的方法必须加入@JavascriptInterface注解
        @JavascriptInterface
        public void toast(String message){
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
        }
    }

2.在js代码中加入

function callToast(){
        toast.toast("js调用了Android中的toast方法");
        }

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

public void addJavascriptInterface(){
        mWebView.addJavascriptInterface(new MyObject(), "toast");
    }

特点

  • 优点:使用简单 仅需要Android对象与JS对象建立映射
  • 缺点:存在严重的漏洞

2.2.2通过WebViewClient的shouldOverrideUrlLoading方法拦截Url

  • 原理:

Android通过WebViewClient的shouldOverrideUrlLoading方法拦截Url,然后按照约定好的协议解析url,调用对应的方法。

  • 使用实例:
  1. 在JS约定所需要的Url协议
 function shouldOverrideUrl(){
        document.location = "demo://webview?arg1=1&arg2=2"
        }
        
<button type="button" id="button2" onclick="shouldOverrideUrl()">shouldOverrideUrlLoading</button>        
  1. 在Android里通过WebViewClient覆写shouldOverrideUrlLoading()方法
 public void shouldOverrideUrlLoading(){
        mWebView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
               Uri url =  request.getUrl();
               if(url.getScheme().equals("demo")){
                   if(url.getAuthority().equals("webview")){
                       Set<String> paramNames = url.getQueryParameterNames();
                       StringBuilder builder = new StringBuilder();
                       for (String paramName: paramNames){
                           String value = url.getQueryParameter(paramName);
                           builder.append(paramName);
                           builder.append("=");
                           builder.append(value);
                           builder.append("; ");
                       }
                       Log.d("WebView", builder.toString());
                   }
               }

                return true;
            }
        });
    }

特点

  • 优点:不存在方式1的漏洞
  • 缺点:JS获取Android方法的返回值复杂

如果JS想得到返回值,只能通过WebView的loadUrl()或evaluateJavascript()去执行JS 方法把返回值传递回去,相关的代码如下:

  mWebView.loadUrl("javascript:callbackValue('dkjkdj')");
 mWebView.evaluateJavascript("javascript:callbackValue('dkjkdj')", null);

2.3通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息

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

  2. 实例:拦截js中prompt()方法
    js中的代码:

function chromeClient(){
         var result = prompt("demo://webview?arg1=1&arg2=2", "");
         alert(result);
        }
<button type="button" id="button3" onclick="chromeClient()">chromeClient</button>        

Android 中通过WebChromeClient中onJsPrompt()方法拦截

 public void onWebChromeClient(){
        mWebView.setWebChromeClient(new WebChromeClient(){
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                return super.onJsAlert(view, url, message, result);
            }

            @Override
            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
                return super.onJsConfirm(view, url, message, result);
            }

            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
                Log.d("WebView", "url = "+ url + "message = " +message);
                return super.onJsPrompt(view, url, message, defaultValue, result);
            }
        });
    }

代码:
https://github.com/1411385476/WebViewDemo

参考资料:
WebView相关类的源码注释
https://mp.weixin.qq.com/s/0vVe-vh_OFW1nbWIv6o_4g
https://www.jianshu.com/p/b9164500d3fb
https://www.jianshu.com/p/3c94ae673e2a

最后

以上就是痴情钥匙为你收集整理的Web与JS交互的全部内容,希望文章能够帮你解决Web与JS交互所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部