js和Java交互注意事项

在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方法一样,进行调用就可以。

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   
}  

你可能感兴趣的:(js和Java交互注意事项)