Android WebView与JavaScript交互

闲来无事,研究了一下WebView与JavaScript间的交互问题,在此,留下此篇博客作为笔记,希望对自己以后的工作还有其他道友有一丢丢的帮助。作为小白,对这方面的知识面实在是太匮乏,如果下文中出现了贻笑大方的错误,请各位不吝赐教。

  • Android中与WebView相关的设置
//表示不支持js,如果想让java和js交互或者本身希望js完成一定的功能请把false改为true。
        wvJs.getSettings().setJavaScriptEnabled(true);

        //用于Js中调用JsInteration中的方法
        wvJs.addJavascriptInterface(new JsInteration(), "control");

        // 启用WebView访问文件数据
        wvJs.getSettings().setAllowFileAccess(true);

        //WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等
        wvJs.setWebChromeClient(new WebChromeClient());

        //WebViewClient主要为WebView处理各种通知、请求事件。setWebViewClient()该方法作用于点击链接
        // 时调用,点击跳转时,加载新的webview资源,并可以在加载前后添加操作,比如添加缓冲对话框,该
        // 方法的作用使得点击链接的响应在WebView内执行,而不是手机浏览器
        wvJs.setWebViewClient(new WebViewClient(){
            // 用于加载新WebView,返回true代表着用完就消费掉
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });

        //设置是否支持缩放,我这里为false,默认为true
        wvJs.getSettings().setSupportZoom(true);
        //设置是否显示缩放工具,默认为false
        wvJs.getSettings().setBuiltInZoomControls(true);
        // 设置缩放比例
        wvJs.setInitialScale(35);

        //一般很少会用到这个,用WebView组件显示普通网页时一般会出现横向滚动条,这样会导致页面查看起来非常不方便。LayoutAlgorithm是一个枚举,用来控制html的布局,总共有三种类型:
        //NORMAL:正常显示,没有渲染变化。
        //SINGLE_COLUMN:把所有内容放到WebView组件等宽的一列中。
        //NARROW_COLUMNS:可能的话,使所有列的宽度不超过屏幕宽度。
        wvJs.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);

        //设置默认的字体大小,默认为16,有效值区间在1-72之间
        wvJs.getSettings().setDefaultFontSize(16);

        //WebView显示html文件时,若要达到和PC上浏览器显示的效果完全一样,只需对WebView做一下设置即可:
        //适应全屏
        //39 适应竖屏
        //57 适应横屏
        wvJs.setInitialScale(39);

        //几种加速WebView加载的方法,提高渲染的优先级
        //把图片加载放在最后来加载渲染
        wvJs.getSettings().setBlockNetworkImage(true);

        // 将图片调整到适合WebView大小,设置该属性可通过双击或手指移动实现缩放
        wvJs.getSettings().setUseWideViewPort(true);

        // 支持多窗口
        wvJs.getSettings().supportMultipleWindows();

        // 设置自动加载图片
        wvJs.getSettings().setLoadsImagesAutomatically(true);

        // 如果需要用户输入账号密码,必须设置支持手势焦点
        wvJs.requestFocusFromTouch();

        // 取消滚动条
        wvJs.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);

        // 设置缓存模式
        wvJs.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
        // 启用缓存
        wvJs.getSettings().setAppCacheEnabled(true);

相关设置的具体作用,已在注释中有详细介绍。想要了解更详细的操作,请点这里

  • WebView加载要显示的网页信息

(1) 如果要加载网络上的网页信息,需要添加访问网络的权限
(2) 加载网页

    webView.loadUrl("http://www.google.com");// 互联网
    webView.loadUrl("file:///android_asset/XX.html");// 本地文件,本地文件存放在:assets文件中

(3) loadData()和loadDataWithBaseURL()使用的区别

loadData()中的html data中不能包含’#’, ‘%’, ‘\’, ‘?’四中特殊字符,出现这种字符就会出现解析错误,显示找不到网页还有部分html代码。
处理方法:我们需要用UrlEncoder编码为%23, %25, %27, %3f 。 可以使用以下两种代码,data为string类型的html代码

webView.loadData(URLEncoder.encode(data, "utf-8"), "text/html", "utf-8");   
webView.loadDataWithBaseURL(null, data, "text/html", "utf-8", null);
  • 编写用于JS调用的接口
/**
     * 用于js中调用Android端方法的接口
     */
    public class JsInteration {

        @JavascriptInterface
        public void toastMessage(String message, String json) {
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
        }
    /*这里讲实现的内容放在了runOnUiThread中,是为了在Android调用js中方法后,可以立即更新UI操作,线程安全*/
        @JavascriptInterface
        public void onSumResult(final String str) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //            Log.i(LOGTAG, "onSumResult result=" + result);
                    Toast.makeText(MainActivity.this, "result = " + str, Toast.LENGTH_SHORT).show();
                    tvJs.setText("result = " + str.toString());
                    JSONObject json = null;
                    try {
                        json = new JSONObject(str);
                        Log.e("json", json.toString());
                        Log.e("json1", json.get("section").toString());
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
  • 编写html和js
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script>
    function sayHello() {
        alert("Hello")
    }

    function alertMessage(message) {
        alert(message)
    }

var json = {"section":
{
        "title":"circle",
        "signing":[
            {
                "id":"1234",
                "name":"安硕圈"
            },
            {
                "id":"1235",
                "name":"海事圈"
            }
            ]
        }
};

var s = "我是张三";
var ss = JSON.stringify(json);
    function toastMessage(message) {
        window.control.toastMessage(message)
    }

    function sumToJava(number1, number2){
    //control是在WebView中注册的对象,主要用于js中调用对象中的方法
       window.control.onSumResult(ss)
    }
</script>
Java-Javascript Interaction In Android
</html>

下面是Android官网对addJavaScriptInterface的介绍:

*This method can be used to allow JavaScript to control the host application. This is a powerful feature, but also presents a security risk for applications targeted to API level JELLY_BEAN or below, because JavaScript could use reflection to access an injected object's public fields. Use of this method in a WebView containing untrusted content could allow an attacker to manipulate the host application in unintended ways, executing Java code with the permissions of the host application. Use extreme care when using this method in a WebView which could contain untrusted content.
*JavaScript interacts with Java object on a private, background thread of this WebView. Care is therefore required to maintain thread safety.
*The Java object's fields are not accessible.

当然,Android WebView注入js对象会产生漏洞,具体解决方案请见:Android WebView的Js对象注入漏洞解决方案

  • Android端调用js中的方法
wvJs.loadUrl("file:///android_asset/as.html");
testMethod();

testMethod内容:

//测试在Android端调用js中的方法
    private void testMethod(WebView webView) {
        String call;
//        call = "javascript:sayHello()";
//        call = "javascript:alertMessage(\"" + "content" + "\")";
//        call = "javascript:toastMessage(\"" + "content" + "\")";
        call = "javascript:sumToJava(1,2)";
        webView.loadUrl(call);
    }

好了,本次总结就告一段落,欢迎各位大驾来吐槽!

最后,附上本人的测试程序,希望对你有那么一丢丢的作用:传送门

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值