美文网首页我爱编程
js和Java交互注意事项

js和Java交互注意事项

作者: anmi7 | 来源:发表于2017-02-28 10:24 被阅读0次

    在Android中有WebView Widget,它内置了WebKit引擎,同时,WebKit也是Mac OS X的Safari网页浏览器的基础。WebKit是一个开源的浏览器引擎,Chrome浏览器也是基于它的。所以很多表现WebView和Chrome是一样的。
    该篇针对Android 中 的WebView 和 JS 交互需要注意的事项。

    一.WebView相关setting

    1.属性汇总

    WebSettings常用方法:

    setAllowFileAccess 启用或禁止WebView访问文件数据  
    setBlockNetworkImage 是否显示网络图像  
    setBuiltInZoomControls 设置是否支持缩放  
    setCacheMode 设置缓冲的模式  
    setDefaultFontSize 设置默认的字体大小  
    setDefaultTextEncodingName 设置在解码时使用的默认编码  
    setFixedFontFamily 设置固定使用的字体  
    setJavaSciptEnabled 设置是否支持Javascript  
    setLayoutAlgorithm 设置布局方式  
    setLightTouchEnabled 设置用鼠标激活被选项  
    setSupportZoom 设置是否支持变焦  
    

    WebViewClient常用方法:

    doUpdate VisitedHistory 更新历史记录  
    onFormResubmission 应用程序重新请求网页数据  
    onLoadResource 加载指定地址提供的资源  
    onPageFinished 网页加载完毕  
    onPageStarted 网页开始加载  
    onReceivedError 报告错误信息  
    onScaleChanged WebView发生改变  
    shouldOverrideUrlLoading 控制新的连接在当前WebView中打开 
    

    WebChromeClient常用方法:

    onCloseWindow 关闭WebView  
    onCreateWindow 创建WebView  
    onJsAlert 处理Javascript中的Alert对话框  
    onJsConfirm处理Javascript中的Confirm对话框  
    onJsPrompt处理Javascript中的Prompt对话框  
    onProgressChanged 加载进度条改变  
    onReceivedlcon 网页图标更改  
    onReceivedTitle 网页Title更改  
    onRequestFocus WebView显示焦点  
    
    2.页面缩放
    适应手机屏幕:
    webView.getSettings().setUseWideViewPort(true);  
    webView.getSettings().setLoadWithOverviewMode(true); 
    webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
    
    放大设置:
    webView.getSettings().setDisplayZoomControls(true); 
    
    无限放大:
    webView.getSettings().setSupportZoom(true);
    
    比例缩放:
    webView.setInitialScale(50); 
    
    3.页面缓存

    缓存存放地址路径:

    /data/data/package_name/cache/
    /data/data/package_name/database/webview.db
    /data/data/package_name/database/webviewCache.db

    缓存模式

    LOAD_CACHE_ONLY:  不使用网络,只读取本地缓存数据  
    LOAD_DEFAULT:  根据cache-control决定是否从网络上取数据。  
    LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式  
    LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.  
    LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
    

    如:www.taobao.com的cache-control为no-cache,在模式LOAD_DEFAULT下,无论如何都会从网络上取数据,如果没有网络,就会出现错误页面;在LOAD_CACHE_ELSE_NETWORK模式下,无论是否有网络,只要本地有缓存,都使用缓存。本地没有缓存时才从网络上获取。www.360.com.cn的cache-control为max-age=60,在两种模式下都使用本地缓存数据。
    总结:根据以上两种模式,建议缓存策略为,判断是否有网络,有的话,使用LOAD_DEFAULT,无网络时,使用LOAD_CACHE_ELSE_NETWORK。

    清理cache 和历史记录

    webView.clearCache(true);   
    webView.clearHistory(); 
    
    4、错误页面

    出现网络异常、地址不存在的错误问题,而默认的错误页面比较难看,这时需要加载自己设计好的页面。

    webView.setWebViewClient(new WebViewClient(){   
        public boolean shouldOverrideUrlLoading(WebView view, String url) {  
                     view.loadUrl(url);  
                     return true;  
        }  
                   
        //显示错误页面  
        @Override  
        public void onReceivedError(WebView view, int errorCode,  
                    String description, String failingUrl) {  
            // 静态页存放在assets文件夹下  
            view.loadUrl("file:///android_asset/www/index.html");  
            super.onReceivedError(view, errorCode, description, failingUrl);  
        }  
    });   
    
    5、加载进度
    /* 
     * 需要自己定义一个进度条控件 
     * 这里已经定义好了progressBar 
     */  
    webView.setWebChromeClient(new WebChromeClient(){  
        @Override  
        public void onProgressChanged(WebView view, int newProgress) {  
            // TODO Auto-generated method stub  
            if(newProgress < 100){  
                //更新当前进度  
                progressBar.setVisibility(View.VISIBLE);  
                progressBar.setProgress(newProgress);  
            }else{  
                //加载完成因此进度条  
                progressBar.setVisibility(View.GONE);  
            }  
            super.onProgressChanged(view, newProgress);  
        }  
    });  
    

    二.WebView和js交互

    1.调用js代码
    在程序中调用js代码,只需要将webview控件的支持js的属性设置为true,,然后通过loadUrl就可以直接进行调用,如下所示:

    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.loadUrl("javascript:test()");
    

    2.js调用android中java代码的方法
    在html中调用java代码,需要在webview控件中添加javascriptInterface。如下所示:

    mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "images");
    
     final class DemoJavaScriptInterface {
            DemoJavaScriptInterface() {
            }
    
            @JavascriptInterface
            public void clickOnAndroid() {
                mHandler.post(new Runnable() {
                    public void run() {
                        //调用js中wave方法;("javascript:"+js方法)固定写法
                        mWebView.loadUrl("javascript:wave()");
                    }
                });
            }
        }
    

    注意:对于安卓开发有一段时间的人来说,知道安卓4.4以前谷歌的webview存在安全漏洞,网站可以通过js注入就可以随便拿到客户端的重要信息,甚至轻而易举的调用本地代码进行流氓行为,谷歌后来发现有此漏洞后,增加了防御措施,如果要是js调用本地代码,开发者必须在代码申明JavascriptInterface,例如在4.0之前我们要使得webView加载js只需本文中介绍的方法。4.4之后调用需要在调用方法加入加入@JavascriptInterface注解,如果代码无此申明,那么也就无法使得js生效,也就是说这样就可以避免恶意网页利用js对安卓客户端的窃取和攻击。

    在网页中,只需要像调用js方法一样,进行调用就可以。
    <div id='b'><a onclick="window.demo.clickOnAndroid()">b.c</a></div>

    3.Java代码调用js并传参
    首先需要带参数的js函数,如function test(str),然后只需在调用js时传入参数即可,如下所示:
    mWebView.loadUrl("javascript:test('aa')");

    三.注意事项

    1.有时会出现混淆打包失效问题,需要在proguard.cfg文件中添加

    //表示WebHost类下的所有方法不被混淆
    -keep public class com.cx.httpwebview.WebHost{  
        public <methods>  
    }  
    

    相关文章

      网友评论

        本文标题:js和Java交互注意事项

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