WebView详解学习
参考:
https://www.jianshu.com/p/3c94ae673e2a
https://blog.csdn.net/carson_ho/article/details/64904691
WebView的相关设置
WebView的前进后退
//是否可以后退 Webview.canGoBack() //后退网页 Webview.goBack() //是否可以前进 Webview.canGoForward() //前进网页 Webview.goForward() //以当前的index为起始点前进或者后退到历史记录中指定的steps //如果steps为负数则为后退,正数则为前进 Webview.goBackOrForward(intsteps)
使用:
public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) { mWebView.goBack(); return true; } return super.onKeyDown(keyCode, event); }
WebView的Setting设置
//声明WebSettings子类 WebSettings webSettings = webView.getSettings(); //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript webSettings.setJavaScriptEnabled(true); // 若加载的 html 里有JS 在执行动画等操作,会造成资源浪费(CPU、电量) // 在 onStop 和 onResume 里分别把 setJavaScriptEnabled() 给设置成 false 和 true 即可 //支持插件 webSettings.setPluginsEnabled(true); //设置自适应屏幕,两者合用 webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小 webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小 //缩放操作 webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。 webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放 //隐藏原生的缩放控件 webSettings.setDisplayZoomControls(false); //其他细节操作 //关闭webview中缓存 webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //设置可以访问文件 webSettings.setAllowFileAccess(true); //支持通过JS打开新窗口 webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持自动加载图片 webSettings.setLoadsImagesAutomatically(true); //设置编码格式 webSettings.setDefaultTextEncodingName("utf-8");
WebView缓存
-
当加载 html 页面时,WebView会在/data/data/包名目录下生成 database 与 cache 两个文件夹
-
请求的 URL记录保存在 WebViewCache.db,而 URL的内容是保存在 WebViewCache 文件夹下
//优先使用缓存: WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //缓存模式如下: //LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据 //LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。 //LOAD_NO_CACHE: 不使用缓存,只从网络获取数据. //LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。 //不使用缓存: WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
WebViewClient VS WebChromeClient
WebViewClient :处理各种通知 & 请求事件
WebChromeClien:辅助 WebView 处理 Javascript 的对话框,网站图标,网站标题等等。
WebViewClient常用方法:
-
shouldOverrideUrlLoading()
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; }
可以拿到跳转的url的相关内容,然后再做加载
-
onPageStarted()
-
onPageFinished()
-
onLoadResource()
@Override public boolean onLoadResource(WebView view, String url) { //设定加载资源的操作 }
-
onReceivedError()
@Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){ switch(errorCode) { case HttpStatus.SC_NOT_FOUND: view.loadUrl("file:///android_assets/error_handle.html"); break; } }
WebChromeClient常用方法
-
onProgressChanged()
@Override public void onProgressChanged(WebView view, int newProgress) { if (newProgress < 100) { String progress = newProgress + "%"; progress.setText(progress); } else { } });
-
onReceivedTitle()
@Override public void onReceivedTitle(WebView view, String title) { titleview.setText(title); }
WebView与网页的交互
Android调用网页
通过loadUrl调用
-
通过loadUrl我们可以加载Url对应的网页
-
实现JS注入Android
webView加载完url之后,在webViewclient中对特定的网页实现注入一段js代码
@Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if("https://12348.yunnan.laway.cn/pufa/yunnan/mobile/#/advice-choose".equals(url)){ view.loadUrl("javascript: " + JS_DELETE_BACK); } } private String JS_DELETE_BACK ="(function () {document.getElementsByClassName(\"left sliding\")[0].innerHTML=\"\"})()";
通过evaluateJavascript调用
注意:
-
因为该方法的执行不会使页面刷新,而第一种方法(loadUrl )的执行则会。
-
Android 4.4 后才可使用
loadUrl()
不是 Android 注入js的正经解决方法。官方在 Android 4.4+ 之后,提供了原生的方法支持调用。
webview.evaluateJavascript("javascript:" + JS_DELETE_BACK, new ValueCallback<String>() { @Override public void onReceiveValue(String value) { System.out.println(value); } });
调用方法和 loadUrl()
非常类似,区别是增加了一个 callback 方法可以获取到 JS 返回的值。
网页调用Android
WebView的addJavascriptInterface()
通过这个方法,将js中的方法与Android的对象进行映射 ,从而进行调用;
webview.addJavascriptInterface(new JavaScriptinterface(), "android"); public class JavaScriptinterface { /** 与js交互时用到的方法,在js里直接调用的 */ @JavascriptInterface public void scanRqCode() { Intent intent = new Intent(MainActivity.this, CaptureActivity.class); startActivityForResult(intent, REQUEST_RQ_CODE); } }
js调用:
<script> function callAndroid(){ // 由于对象映射,所以调用test对象等于调用Android映射的对象 } </script>
WebViewClient 的shouldOverrideUrlLoading ()
通过这个方法回调拦截 url ,在url中我们放入对应的参数,在解析到对应的参数的时候再重新让webView 去加载对应的url。
WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()
通过这个方法回调拦截JS对话框alert()、confirm()、prompt() 消息;然后自己处理相关的信息然后再做对应的操作。
总结