文章目录
WebView总结
概述
- 显示网页
- 实现混合开发
权限申请
<uses-permission android:name="android.permission.INTERNET" />
WebView使用
加载网页
webView.getSettings().setJavaScriptEnabled(true);
//加载网页
String url = "https://www.baidu.com";
webView.loadUrl(url);
//加载资源文件里的网页
webView.loadUrl("file:///android_asset/index.html");
//加载html字符串
String html = "<html><h1>hello webview</h1></html>";
webView.loadData(html, "text/html", null);
WebView生命周期
WebView生命周期一般依赖Activity
@Override
protected void onResume() {
super.onResume();
webView.onResume();
}
@Override
protected void onPause() {
super.onPause();
webView.onPause();
}
WebView常用方法
//操作WebView前进和后退
if (webView.canGoBack()) {
webView.goBack();
}
if (webView.canGoForward()) {
webView.goForward();
}
//刷新页面,重新加载所有资源
webView.reload();
//停止加载
webView.stopLoading();
//清除缓存
webView.clearCache(true);
//清除历史记录
webView.clearHistory();
//清除自动完成填充的表单数据
webView.clearFormData();
WebSettings
负责对WebView配置和管理
WebSettings settings = webView.getSettings();
//WebView支持js
settings.setJavaScriptEnabled(true);
//适应屏幕
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
//缩放操作
settings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
settings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
settings.setDisplayZoomControls(false); //隐藏原生的缩放控件
settings.setTextZoom(2);//设置文本的缩放倍数,默认为 100
//使用缓存
//LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
//LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
//LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
//LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
settings.setCacheMode(WebSettings.LOAD_NO_CACHE)
WebViewClient
负责处理各种通知和请求事件
webView.setWebViewClient(new WebViewClient() {
//重定向url
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
//开始加载时调用
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
Log.e(TAG, "网页开始加载");
}
//加载完成时调用
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.e(TAG, "网页加载结束");
}
});
WebChromeClient
负责处理JavaScript相关,如对话框、网页图标、网页标题等
webView.setWebChromeClient(new WebChromeClient() {
//加载进度
//加载完毕在onProgressChanged()里监听比较准确
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
Log.e("TAG", "newProgress: " + newProgress);
}
//获取网页title
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
Log.e("TAG", "title: " + title);
}
//获取网页图标
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
img.setImageBitmap(icon);
}
});
Android与JS交互
JS定义
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<div id="content"></div>
<button onclick="callAndroid()">JS调Android</button>
<button onclick="callAndroid2()">JS调Android,带参数</button>
<script>
function androidCallJs() {
document.getElementById("content").innerHTML = "Android调JS";
}
function androidCallJs(param) {
document.getElementById("content").innerHTML = "Android调JS,参数:" + param;
}
function callAndroid() {
window.android.jsCallAndroid();
}
function callAndroid2() {
window.android.jsCallAndroid("hello android");
}
</script>
</body>
</html>
Android调JS
WebSettings settings = webView.getSettings();
//支持js
settings.setJavaScriptEnabled(true);
webView.loadUrl("file:///android_asset/index.html");
//Android调JS
webView.loadUrl("javascript:androidCallJs()");
//Android调JS,带参数
webView.loadUrl("javascript:androidCallJs('hello js')");
JS调Android
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
webView.addJavascriptInterface(new AndroidInterface(), "android");
webView.loadUrl("file:///android_asset/index.html");
class AndroidInterface {
@JavascriptInterface
public void jsCallAndroid() {
Toast.makeText(context, "JS调Android", Toast.LENGTH_SHORT).show();
}
@JavascriptInterface
public void jsCallAndroid(String param) {
Toast.makeText(context, "JS调Android,带参数:" + param, Toast.LENGTH_SHORT).show();
}
}
WebView其他问题
Android5.0 WebView中Http和Https混合问题
在Android 5.0上 Webview 默认不允许加载 Http 与 Https 混合内容,解决办法:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
参数说明:
MIXED_CONTENT_ALWAYS_ALLOW
:允许从任何来源加载内容,即使起源是不安全的;MIXED_CONTENT_NEVER_ALLOW
:不允许Https加载Http的内容,即不允许从安全的起源去加载一个不安全的资源;MIXED_CONTENT_COMPATIBILITY_MODE
:当涉及到混合式内容时,WebView 会尝试去兼容最新Web浏览器的风格。
设置WebView接受所有网站的证书
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// handler.cancel();// Android默认的处理方式
handler.proceed();// 接受所有网站的证书
// handleMessage(Message msg);// 进行其他处理
}
});
**注意:**一定要移除super.onReceivedSslError(view, handler, error)
方法,否则不生效
WebView性能优化
加载优化
WebView图片资源等页面加载完后在处理。
//在网页加载时暂时不加载图片
settings.setLoadsImagesAutomatically(false);
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
//页面加载完后再加载图片
if (newProgress == 100) {
settings.setLoadsImagesAutomatically(true);
}
}
});
开启硬件加速
在开启硬件加速后,WebView渲染更加快速,可能会出现界面闪烁.
解决办法,在过渡期前关闭硬件加速,过渡期后开启。
//关闭硬件加速
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
//开启硬件加速
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
增加进度条
定义错误页面
webView.setWebViewClient(new WebViewClient(){
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (errorCode == 404) {
//用javascript隐藏系统定义的404页面信息
String data = "Page NO FOUND!";
view.loadUrl("javascript:document.body.innerHTML=\"" + data + "\"");
} else {
if (webListener!=null){
webListener.showErrorView();
}
}
}
});
WebView后台优化
WebView在后台的时候,会调用onStop()
方法,此时应该关闭js交互,在onResume()
时再开启。
@Override
protected void onResume() {
super.onResume();
if (webView != null) {
webView.onResume();
settings.setJavaScriptEnabled(true);
}
}
@Override
protected void onPause() {
super.onPause();
if (webView != null) {
webView.onPause();
}
}
@Override
protected void onStop() {
super.onStop();
if (webView != null) {
settings.setJavaScriptEnabled(false);
}
}