美文网首页学习笔记
Android WebView与JS交互实例

Android WebView与JS交互实例

作者: Jinbeen | 来源:发表于2019-01-12 23:14 被阅读51次
    与js交互示例.jpg

    正文

    一切基于项目WebViewStudy来说明,都是最小单元案例,可作为参考研究,本文从几个方面来讲解:

    • 1、Java调用WebView里的js代码(传递参数)
    • 2、WebView里的js代码调用Java本地方法(传递参数)
    • 3、外部注入js代码
    • 4、WebView长按事件

    相关JS代码:

    <html>
    <head>
        <title>js调用android原生代码</title>
        <meta http-equiv="Content-Type" content="text/html;charset=gb2312">
        <meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,minimal-ui">
        <script type="text/javascript">
            function javacalljs(){
                 document.getElementById("content").innerHTML +=
                     "<br\>java调用了js函数,无参";
            }
    
            <!--这里取到的是 android端传过来的数据-->
            function javacalljswithargs(data){
                 document.getElementById("content").innerHTML +=
                     ("<br\>"+data);
            }
    
        </script>
    </head>
    <body>
        <br/><br/>
        <li><a onClick="window.injectedObject.startFunction()">点击调用java代码</a></li>
        <!--可以将android端传过来的数据,处理后,放在这里再传给android端-->
        <li><a onClick="window.injectedObject.startFunction('我是网页传出来的数据')">点击调用java代码并传递参数</a></li><br/>
    <div id="content">内容显示</div>
    </body>
    </html>
    

    Java调用WebView里的js代码(传递参数)

    // 告诉WebView启用JavaScript执行。默认的是false。
    ws.setJavaScriptEnabled(true);
    1、如果点击调用就直接执行就好:

    // 无参数调用
    webView.loadUrl("javascript:javacalljs()");
    // 传递参数调用
    webView.loadUrl("javascript:javacalljswithargs('" + "android传入到网页里的数据,有参" + "')");
    

    2、如果是显示后就调用,注意放在html显示完成之后
    MyWebViewClient.java

    @Override
        public void onPageFinished(WebView view, String url) {
            // 无参数调用
            webView.loadUrl("javascript:javacalljs()");
            // 传递参数调用
            webView.loadUrl("javascript:javacalljswithargs('" + "android传入到网页里的数据,有参" + "')");
            super.onPageFinished(view, url);
        }
    
        /**
         * 4.4以上可用 evaluateJavascript 效率高
         */
        private void load(String jsCode) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                evaluateJavascript(jsCode, null);
            } else {
                loadUrl(jsCode);
            }
        }
    

    WebView里的js代码调用Java本地方法(传递参数)

    这里有一个js点击方法:

    <li><a onClick="window.injectedObject.startFunction()">点击调用java代码</a></li>
    <li><a onClick="window.injectedObject.startFunction('我是网页传出来的数据')">点击调用java代码并传递参数</a></li>
    

    实现与js交互接口:

    webView.addJavascriptInterface(new MyJavascriptInterface(this), "injectedObject");
    

    这里的"injectedObject"对应js里的"window.injectedObject.startFunction()",其中MyJavascriptInterface.java:

    /**
     * Created by jingbin on 2016/11/17.
     * js通信接口
     */
    public class MyJavascriptInterface {
        private Context context;
    
        public MyJavascriptInterface(Context context) {
            this.context = context;
        }
    
        /**
         * 前端代码嵌入js:
         * imageClick 名应和js函数方法名一致
         *
         * @param src 图片的链接
         */
        @JavascriptInterface
        public void imageClick(String src) {
            Log.e("imageClick", "----点击了图片");
            Log.e("src", src);
        }
    
        /**
         * 前端代码嵌入js
         * 遍历<li>节点
         *
         * @param type    <li>节点下type属性的值
         * @param item_pk item_pk属性的值
         */
        @JavascriptInterface
        public void textClick(String type, String item_pk) {
            if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(item_pk)) {
                Log.e("textClick", "----点击了文字");
                Log.e("type", type);
                Log.e("item_pk", item_pk);
            }
        }
    
        /**
         * 网页使用的js,方法无参数
         */
        @JavascriptInterface
        public void startFunction() {
            Log.e("startFunction", "----无参");
        }
    
        /**
         * 网页使用的js,方法有参数,且参数名为data
         *
         * @param data 网页js里的参数名
         */
        @JavascriptInterface
        public void startFunction(String data) {
            Log.e("startFunction", "----有参" + data);
        }
    }
    

    且对标里面的两个方法:

        /**
         * 网页使用的js,方法无参数
         */
        @JavascriptInterface
        public void startFunction() {
            Log.e("startFunction", "----无参");
        }
    
        /**
         * 网页使用的js,方法有参数,且参数名为data
         *
         * @param data 网页js里的参数名
         */
        @JavascriptInterface
        public void startFunction(String data) {
            Log.e("startFunction", "----有参" + data);
        }
    

    外部注入js代码

    有时候我们得到一个网页,这个网页并不是我们订制的,里面没有我们调用的js代码,这时候我们可在前端直接注入js的。
    比如 网页里面有图片,我们点击图片想要查看图片和保存图片到本地,这时候网页并没有实现这个js方法供我们调用,但是我们可以注入js代码,来实现这个需求。

    在html加载完成之后,我们调用这段js:

    // 这段js函数的功能就是,遍历所有的img节点,并添加onclick函数,函数的功能是在图片点击的时候调用本地java接口并传递url过去
    webView.loadUrl("javascript:(function(){" +
            "var objs = document.getElementsByTagName(\"img\");" +
            "for(var i=0;i<objs.length;i++)" +
            "{" +
            "objs[i].onclick=function(){window.injectedObject.imageClick(this.getAttribute(\"src\"));}" +
            "}" +
            "})()");
    

    这时候再看MyJavascriptInterface.java里的imageClick方法:

        /**
         * 前端代码嵌入js:
         * imageClick 名应和js函数方法名一致
         *
         * @param src 图片的链接
         */
        @JavascriptInterface
        public void imageClick(String src) {
            Log.e("imageClick", "----点击了图片");
            Log.e("src", src);
        }
    

    src即为图片链接,可以作为显示和下载用。

    WebView长按事件

    webView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            final WebView.HitTestResult hitTestResult = webView.getHitTestResult();
            // 如果是图片类型或者是带有图片链接的类型
            if (hitTestResult.getType() == WebView.HitTestResult.IMAGE_TYPE ||
                    hitTestResult.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
                // 弹出保存图片的对话框
                new AlertDialog.Builder(WebViewActivity.this)
                        .setItems(new String[]{"查看大图", "保存图片到相册"}, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                String picUrl = hitTestResult.getExtra();
                                //获取图片
                                Log.e("picUrl", picUrl);
                                switch (which) {
                                    case 0:
                                        break;
                                    case 1:
                                        break;
                                    default:
                                        break;
                                }
                            }
                        })
                        .show();
                return true;
            }
            return false;
        }
    });
    

    参考资料

    相关文章

      网友评论

        本文标题:Android WebView与JS交互实例

        本文链接:https://www.haomeiwen.com/subject/zlizrqtx.html