概述
在应用的开发过程中,经常遇到需要经常变化的页面,一般针对这种页面,我们会用WebView
来实现.如隐私条款等等.并且随着 hybrid
的兴起,webview
将会更加常用.
loadDataWithBaseURL 与 loadData
loadData
//方法原型
loadData(String data, String mimeType, String encoding)
loadData
用于加载一段html
文本,这个和loadUrl
是有区别的,
loadUrl
是根据一个url
来加载一个网页,他们各有利弊,
参考:WebView到底该使用loadUrl还是loadData
其中loadData
使用 #、%、\、?
四种字符易出现问题.
%
会报找不到页面错误,页面全是乱码。乱码样式见符件。
#
会让你的goBack
失效,但canGoBack
是可以使用的。于是就会产生返回按钮生效,但不能返回的情况。
\
会被当做转义字符.
如果出现乱码问题,需要将encoding
参数设置为utf-8
.
mimeType
,指定mineType
类型,如text/html; charset=utf-8
loadDataWithBaseURL
//方法原型
public void loadDataWithBaseURL(String baseUrl, String data,
String mimeType, String encoding, String failUrl) {
}
public void loadData(String data, String mimeType, String encoding) {
}
public void loadUrl(String url) {
}
public void loadUrl(String url,Map<Stirng,String> extraHeaders) {
}
loadDataWithBaseURL
可以指定相对根路径,也可以指定历史Url
。
baseUrl
相对根路径,常见于WebView
中的超链接或者是image
元素,如使用绝对路径传""
即可。
比如, 我们的data
格式:
String body ="示例:这里有个img标签,地址是相对路径<img src='/uploads/allimg/130923/1FP02V7-0.png' />";
如果baseUrl
没有指定为网站域名,那么这张图片将显示不出来。
常用属性
通过mWebView.getSettings()拿到WebView的设置.
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//支持通过JS打开新窗口
mWebView.getSettings().setSupportZoom(true);//设置是否支持缩放
mWebView.getSettings().setBuiltInZoomControls(true);//设置是否显示缩放工具
webview.getSettings().setDisplayZoomControls(false);//设定缩放控件隐藏
/**http://stackoverflow.com/questions/5448841/what-do-setusewideviewport-and-setloadwithoverviewmode-precisely-do*/
webview.getSettings().setLoadWithOverviewMode(true);// loads the WebView completely zoomed out
webview.getSettings().setUseWideViewPort(true); //makes the Webview have a normal viewport (such as a normal desktop browser), while when false the webview will have a viewport constrained to its own dimensions (so if the webview is 50px*50px the viewport will be the same size)
webview.getSettings().setAllowFileAccess(true); // 允许访问文件
mWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);//一般很少会用到这个,用WebView组件显示普通网页时一般会出现横向滚动条,这样会导致页面查看起来非常不方便。//LayoutAlgorithm是一个枚举,用来控制html的布局,总共有三种类型://NORMAL:正常显示,没有渲染变化。//SINGLE_COLUMN:把所有内容放到WebView组件等宽的一列中。//NARROW_COLUMNS:可能的话,使所有列的宽度不超过屏幕宽度。
mWebView.getSettings().setDefaultFontSize(18);//设置默认的字体大小,默认为16,有效值区间在1-72之间。
//若要考虑兼容3.0以下版本则:
/**http://jingyan.baidu.com/article/48b37f8d0b918e1a646488ec.html*/
if(android.os.Build.VERSION.SDK_INT>=11){
this.getSettings().setDisplayZoomControls(false);
}else{
this.setZoomControlHide(this);
}
//Android 3.0(11) 以下使用以下方法:
//利用java的反射机制
public void setZoomControlHide(View view) {
try {
Class webview = Class.forName("android.webkit.WebView");
Method method = webview.getMethod("getZoomButtonsController");
zoomController = (ZoomButtonsController) method.invoke(this, null);
} catch (Exception e) {
e.printStackTrace();
}
}
更多设置参考:www.cnblogs.com/zgz345/p/3768174.html
-WebView
链接在WebView
内部打开,而非调用系统浏览器的方法.
重写
shouldOverrideUrlLoading
,并且return true
;
WebViewClient与WebChromeClient
WebViewClient
主要帮助WebView
处理各种通知、请求事件的,比如:
onLoadResource
onPageStart
onPageFinish
onReceiveError //错误,可以在此显示一个错误页面
onReceivedHttpAuthRequest
WebChromeClient
主要辅助WebView
处理Javascript
的对话框、网站图标、网站title、加载进度等,比如:
onCloseWindow//关闭WebView
onCreateWindow()
onJsAlert //WebView上alert无效,需要定制WebChromeClient处理弹出
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle//获取title
如果你的WebView
只是用来处理一些v
的页面内容,只用WebViewClient
就行了,如果需要更丰富的处理效果,比如JS、进度条等,就要用到WebChromeClient
比如,我们想要在webview
中相应Email
,tel
的Intent
,我们继承WebViewClient
并重写shouldOverrideUrlLoading
方法
public abstract class WebClient extends android.webkit.WebViewClient {
private final WeakReference<Context> contextWeakReference;
public WebClient(Context context) {
contextWeakReference = new WeakReference<>(context);
}
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("mailto:") || url.startsWith("geo:") || url.startsWith("tel:")) {
final Context context = contextWeakReference.get();
if (context != null) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
context.startActivity(intent);
view.reload();
}
} else {
reloadUrl(view, url);
}
return true;
}
public abstract void reloadUrl(WebView view, String url);
}
onPageFinished:
onReceivedTitle()
方法在goback()
之后无效。
这时,我们可以使用onPageFinished(WebView view, String url)
方法来实现返回及时刷新标题
WebView mWebView = (WebView) findViewById(R.id.mwebview);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
setTitle(view.getTitle());
}
});
处理https请求
android 默认是不处理https请求的,请求https会显示空白。
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
//default
// handler.cancel();
// handler.handleMessage(null);
}
});
cookies 和历史纪录
比如在某些场景中,我们的用户在客户端 登录了,要在 网页中也保持登录状态,则可以使用cookies
来实现,不过需要服务器端配合完成.
//cookies清理
CookieSyncManager.createInstance(this);
CookieSyncManager.getInstance().startSync();
CookieManager.getInstance().removeSessionCookie();
//清理cache 和历史记录
webView.clearCache(true);
webView.clearHistory();
文件下载
我们都知道WebView
中 有这么一个方法
// 方法原型
public void setDownloadListener(DownloadListener listener){}
那么我们只需要自定义一个DownloadListener
即可
public class WebViewDownLoadListener implements DownloadListener {
@Override public void onDownloadStart(String url, String userAgent, String contentDisposition,
String mimetype, long contentLength) {
// 参数含义: url :文件现在链接
// userAgent : 用户浏览器代理
// contentDisposition : 文件描述符
// mimetype : 文件的类型
// contentLength : 文件的长度
}
}
硬件加速
Android自带的WebView非常的鸡肋,比如不能打开pdf,播放视屏也只能打开硬件加速才能支持,但是这里也存在着 问题,比如,在某些机型上会崩溃
这里的做法是在 onPageStart
中关闭硬件加速,在onPageFinish
中开启硬件加速
HTTP/HTTPS混合
在应用全面适配https
后发现 某些图片不再显示了,通过抓包工具发现,是 Https
页面中包含了 Http
的 图片链接。使用混合模式即可。
//http,https 混合使用
// http://developer.android.com/reference/android/webkit/WebSettings.html#setMixedContentMode(int)
if (Build.VERSION.SDK_INT >= 21) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
相关源码:WebViewUtil
参考:泡在网上的日子
Android WebView中获取网页的title (包括调用goback)
WebView到底该使用loadUrl还是loadData