WebView整理归档

来源:互联网 发布:win7网络驱动下载 编辑:程序博客网 时间:2024/05/20 16:34

由于公司的要求,要求我们和H5进行交互,在此我对这段时间趟的坑和学习到的知识进行整理一下,方便以后的学习以及开发。


1.webview在xml文件里的写法,写一个铺满屏幕的webview控件

<WebView    android:id="@+id/introduce"    android:layout_width="match_parent"    android:layout_height="match_parent" />

2.之后我们需要把webview加载出来,用这句代码就可以成功加载出来
网络加载网页
webview.loadUrl("https://www.baidu.com/");
本地加载网页
webview.loadUrl("file:///android_asset/index.html");
3.如果在此过程中,我们发现网页并不能加载出来,那么就有可能是我们在webview的设置过程中遇到了一些问题,可参考下面方法进行加载
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//设置js可以直接打开窗口webview.getSettings().setJavaScriptEnabled(true);//是否允许执行js,默认为false。设置true时,会提醒可能造成XSS漏洞webview.getSettings().setSupportZoom(true);//是否可以缩放,默认truewebview.getSettings().setBuiltInZoomControls(true);//是否显示缩放按钮,默认falsewebview.getSettings().setUseWideViewPort(true);//设置此属性,可任意比例缩放。大视图模式webview.getSettings().setLoadWithOverviewMode(true);//和setUseWideViewPort(true)一起解决网页自适应问题webview.getSettings().setAppCacheEnabled(true);//是否使用缓存webview.getSettings().setDomStorageEnabled(true);//DOM Storage

4.而有些时候我们在不同手机的加载过程中,针对于一些手机可能会出现白屏问题,造成这类问题有可能是我们设置问题,WebView的layerType属性有三个值。
1.none,默认值,
2.software,软件加速,
3.hardware,硬件加速。
出现这种情况,有可能是因为我们设置硬件加速,而那种安卓机型并不支持硬件加速造成的,这时候建议用软件加速,因为默认值可能会造成加载过慢的问题。
android:layerType="software"
5.在此我们知道的是webview主要是完成解析渲染的功能,其他的会交给WebViewClient和WebChromeClient。
WebViewClient
主要负责的是处理各种通知、请求事件的,比如:
onLoadResource:加载资源时响应onPageStart:在加载页面时响应onPageFinish:在加载页面结束时响应onReceiveError:在加载出错时响应
我们可以在onReceiveError的方法里对网页加载失败的情况进行处理,设置默认的界面
WebChromeClient
辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等。
onProgressChanged:返回网页加载进度
onJsAlert :回调alter的弹出,可以自己自定义一下样式
6.当然在加载网页的时候,也遇到了一类编码问题,有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的编码了。
Java中编码和解码函数java.NET.URLEncoder.encode(String s)和java.Net.URLDecoder.decode(String s);
7.返回上一级的问题
public boolean onKeyDown(int keyCode, KeyEvent event) {                         if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {                            mWebView.goBack();                            return true;                         }                        return super.onKeyDown(keyCode, event);           } 
8.webview cookies清理
CookieSyncManager.createInstance(this);   CookieSyncManager.getInstance().startSync();   CookieManager.getInstance().removeSessionCookie(); 
9.清理cache 和历史记录
webView.clearCache(true);   webView.clearHistory(); 

10.判断webview是否已经滚动到页面底端
if(webview.getContentHeight*webview.getScale() == (webview.getHeight()+webview.getScrollY())){ //处于底端 } 

11.加载H5界面的方法,弹出一个alter
webview.loadUrl("javascript:alert(\"I am an alert box!!\")");

12.是H5调用原生的代码
webview.addJavascriptInterface(new WebAppInterface(this), "myInterfaceName");

在H5原生里的写法
 function showAndroidToast(toast)    {        myInterfaceName.showToast(toast);//注意此处的myInterfaceName要和外部传入的名字一致,大小写正确    }
之后回调java的代码
public class WebAppInterface {        Context mContext;        WebAppInterface(Context c) {            mContext = c;        }        //4.2以后必须添加注释才可使用        @JavascriptInterface        public void showToast(String show){            Toast.makeText(MainActivity.this,"可以"+show,Toast.LENGTH_SHORT).show();        }}

大概问题说一下,在4.2版本之前存在addjavascriptInterface接口引起的漏洞。可能导致恶意网页通过Js方法遍历刚刚通过addjavascriptInterface注入进来的类的所有方法从中获取到getClass方法,然后通过反射获取到Runtime对象,进而调用Runtime对象的exec方法执行一些操作,会对我们的程序造成不可挽回的伤害。为了避免这个漏洞,即需要限制Js代码能够调用到的Native方法,官方于是在从4.2开始的版本可以通过为可以被Js调用的方法添加@JavascriptInterface注解来解决。
    当然现在有很多三方开源库已经封装得很好,不需要考虑这一类问题。有需要的大家可以参考
https://github.com/gzsll/WebViewJavascriptBridge这个方案,具体怎么实现的,就需要大家自己去翻看一下内部的源码。
13.最后我还想说下,在H5开发中,相信大家都会遇到这样的一个问题,就是js返回数据的问题,在java里怎么接收,这里介绍一种方法,针对于安卓4.4以后的方案,至于之前的版本涉及的较为复杂,暂不列举
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            wv.evaluateJavascript("localStorage.token", new ValueCallback<String>() {                @Override                public void onReceiveValue(String value) {                }            });        }