WebView 使用
禁止 webview 处理长按事件
设置 OnLongClickListener 把长按事件消费掉。
web.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return true;
}
});
改变字体大小
字体大小的枚举。
public static enum TextSize {
SMALLEST(50),
SMALLER(75),
NORMAL(100),
LARGER(125),
LARGEST(150);
int value;
private TextSize(int var3) {
this.value = var3;
}
}
获取 WebSettings
,然后设置字体大小。
WebSettings st = wv.getSettings();
st.setTextSize(WebSettings.TextSize.LARGER);
显示 html 文本
示例:示例中用到的 html 文本与 TextView 显示 Html 相同。
private static final String T1 = "Tell me the color
";
private static final String H1 = "Tell me the color .
";
private static final String H1_FIX = "Tell me the color.
";
wb1.loadData(T1, "text/html", "UTF-8");
wb2.loadData(H1, "text/html", "UTF-8");
wb3.loadData(H1_FIX, "text/html", "UTF-8");
layout 中放置 WebView
WebView 显示 Html 文本效果图
之前 TextView 显示不出颜色和加粗的 H1
,在 webView 中可以正常显示。
上面的 loadData
方法中指定了 mimeType 为 text/html
,编码类型 UTF-8
。
WebView loadData 中文乱码
使用 loadData
出现中文乱码。
String htmlData = "This is me. 我是文本Text.
";
webView.loadData(htmlData, "text/html", "UTF-8"); // 某些机型出现中文乱码
使用 loadDataWithBaseURL
方法规避中文乱码问题。
webView.loadDataWithBaseURL(null, htmlData, "text/html", "UTF-8", null);
WebView 加载 assets 中的网页
我们把网页文件放到assets
目录中。
设置WebSettings
,允许读取文件等等。
assets
目录的路径以file:///android_asset/
开头。
WebView webView = findViewById(R.id.web2);
String url = "file:///android_asset/drag-to/index.html";
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowContentAccess(true);
webSettings.setDomStorageEnabled(true);
webView.loadUrl(url);
WebView 常见问题
1. 针对加载 webView 中的资源时加快加载的速度优化(主要是针对图片)
原因: html 代码下载到 WebView 后,webkit 开始解析网页各个节点,发现有外部样式文件或者外部脚本文件时,会异步发起网络请求下载文件,但如果在这之前也有解析到 image 节点,那势必也会发起网络请求下载相应的图片。在网络情况较差的情况下,过多的网络请求就会造成带宽紧张,影响到 css 或 js 文件加载完成的时间,造成页面空白 loading 过久。
解决方法: 告诉 WebView 先不要自动加载图片,等页面 finish 后再发起图片加载。
//初始化的时候设置,具体代码在WebView类中
if(Build.VERSION.SDK_INT >= KITKAT) {
//设置网页在加载的时候暂时不加载图片
webView.getSettings().setLoadsImagesAutomatically(true);} else {
webView.getSettings().setLoadsImagesAutomatically(false);}
/**
* 当页面加载完成会调用该方法
* @param view view
* @param url url链接
*/
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//页面finish后再发起图片加载
if(!webView.getSettings().getLoadsImagesAutomatically()) {
webView.getSettings().setLoadsImagesAutomatically(true);
}
}
2.WebView硬件加速导致页面渲染闪烁
原因: 4.0 以上的系统我们开启硬件加速后,WebView 渲染页面更加快速,拖动也更加顺滑。但有个副作用就是,当 WebView 视图被整体遮住一块,然后突然恢复时(比如使用 SlideMenu 将 WebView 从侧边滑出来时),这个过渡期会出现白块同时界面闪烁。
解决方法: 是在过渡期前将 WebView 的硬件加速临时关闭,过渡期后再开启。
//关闭硬件加速
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
//开启硬件加速
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { webview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
3.可以提前显示加载进度条
原因: WebView.loadUrl("url") 不会立马就回调 onPageStarted 或者 onProgressChanged 因为在这一时间段,WebView 有可能在初始化内核,也有可能在与服务器建立连接,这个时间段容易出现白屏,白屏用户体验是很糟糕的。
解决方法: 提前显示进度条虽然不是提升性能 , 但是对用户体验来说也是很重要的一点。
//正确
pb.setVisibility(View.VISIBLE);
mWebView.loadUrl("https://github.com/");//不太好
@Override
public void onPageStarted(WebView webView, String s, Bitmap bitmap) {
super.onPageStarted(webView, s, bitmap);
//设定加载开始的操作
pb.setVisibility(View.VISIBLE);
}
//下面这个是监听进度条进度变化的逻辑
mWebView.getWebChromeClient().setWebListener(interWebListener);
mWebView.getWebViewClient().setWebListener(interWebListener);
private InterWebListener interWebListener = new InterWebListener() {
@Override
public void hindProgressBar() {
pb.setVisibility(View.GONE);
}
@Override
public void showErrorView() {
}
@Override
public void startProgress(int newProgress) {
pb.setProgress(newProgress);
}
@Override
public void showTitle(String title) {
}
};
4. WebView密码明文存储漏洞优化
原因: WebView 默认开启密码保存功能 mWebView.setSavePassword(true),如果该功能未关闭,在用户输入密码时,会弹出提示框,询问用户是否保存密码,如果选择”是”,密码会被明文保到 /data/data/com.package.name/databases/webview.db 中,这样就有被盗取密码的危险。
解决方法: 通过 WebSettings.setSavePassword(false) 关闭密码保存提醒功能。
//设置是否开启密码保存功能,不建议开启,默认已经做了处理,存在盗取密码的危险
WebView.setSavePassword(false);
5.自定义加载异常 error 的状态页面,比如下面这些方法中可能会出现 error
原因: 当WebView加载页面出错时(一般为404 NOT FOUND,Android WebView会默认显示一个出错界面。当WebView加载出错时,会在WebViewClient实例中的onReceivedError()`,还有onReceivedTitle
方法接收到错误。
解决方法: 自定义错误页面样式。
/**
* 请求网络出现error
* @param view view
* @param errorCode 错误
* @param description description
* @param failingUrl 失败链接
*/
@Override
public void onReceivedError(WebView view, int errorCode, String description, String
failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
if (errorCode == 404) {
//用javascript隐藏系统定义的404页面信息
String data = "Page NO FOUND!";
view.loadUrl("javascript:document.body.innerHTML=\"" + data + "\"");
} else {
if (webListener!=null){
webListener.showErrorView();
}
}
}
// 向主机应用程序报告Web资源加载错误。这些错误通常表明无法连接到服务器。
// 值得注意的是,不同的是过时的版本的回调,新的版本将被称为任何资源(iframe,图像等)
// 不仅为主页。因此,建议在回调过程中执行最低要求的工作。
// 6.0 之后
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
X5WebUtils.log("服务器异常"+error.getDescription().toString());
}
//ToastUtils.showToast("服务器异常6.0之后");
//当加载错误时,就让它加载本地错误网页文件
//mWebView.loadUrl("file:///android_asset/errorpage/error.html");
if (webListener!=null){
webListener.showErrorView();
}
}
/**
* 这个方法主要是监听标题变化操作的
* @param view view
* @param title 标题
*/
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
if (title.contains("404") || title.contains("网页无法打开")){
if (webListener!=null){
webListener.showErrorView();
}
} else {
// 设置title
}
}