AndroidWebView基础应用详解
附GitHub源码:WebViewExplore
一、WebView的基础配置
WebSettings ws = getSettings();
ws.setBuiltInZoomControls(true);// 隐藏缩放按钮
ws.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);// 排版适应屏幕
ws.setUseWideViewPort(true);// 可任意比例缩放
ws.setLoadWithOverviewMode(true);// setUseWideViewPort方法设置webview推荐使用的窗口。setLoadWithOverviewMode方法是设置webview加载的页面的模式。
ws.setSaveFormData(true);// 保存表单数据
ws.setJavaScriptEnabled(true); // 是否能与JS交互【如果业务中无JS交互,建议将此项关闭】
ws.setGeolocationEnabled(true);// 启用地理定位【如果业务中无此业务,建议将此项关闭】
ws.setDomStorageEnabled(true);
ws.setJavaScriptCanOpenWindowsAutomatically(true);//允许JS Alert对话框等打开【如果业务中无此业务,建议将此项关闭】
ws.setSupportMultipleWindows(true);// 新加
二、WebView支持播放音乐
//是否支持播放音乐
ws.setPluginState(WebSettings.PluginState.ON);
ws.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
//是否需要用户点击才播放
ws.setMediaPlaybackRequiresUserGesture(true);
三、WebView支持视频播放
Android WebView播放视频(包括全屏播放)
四、WebChromeClient
setWebChromeClient(new XWebChromeClient());
其具体覆盖方法如下:
public static class XWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
Log.d(TAG, "onProgressChanged---> newProgress:" + newProgress);
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
Log.d(TAG, "onReceivedTitle---> title:" + title);
if (webTitleCallBack != null) {
webTitleCallBack.onReceived(title);
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
if (title.contains("404") || title.contains("500") || title.contains("Error")) {
view.loadUrl("about:blank"); // 避免出现默认的错误界面
// 在这里可以考虑显示自定义错误页
// showErrorPage();
}
}
}
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
Log.d(TAG, "icon:" + icon);
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.d(TAG, "onJsAlert");
return super.onJsAlert(view, url, message, result);
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
Log.d(TAG, "onJsConfirm");
return super.onJsConfirm(view, url, message, result);
}
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Log.d(TAG, "onConsoleMessage");
return super.onConsoleMessage(consoleMessage);
}
@Override
public void onPermissionRequest(PermissionRequest request) {
super.onPermissionRequest(request);
Log.d(TAG, "onPermissionRequest---> request:" + request);
}
}
五、WebViewClient
setWebViewClient(new XWebViewClient());
其具体覆盖方法如下:
public class XWebViewClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
Log.d(TAG, "onPageStarted---> url:" + url);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.d(TAG, "onPageFinished---> url:" + url);
}
//Android6.0之前的方法 【在新版本中也可能被调用,所以加上一个判断,防止重复显示】
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// 断网或者网络连接超时
showReceivedErrorPage(view, errorCode, description, failingUrl);
}
}
//6.0新增方法
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
super.onReceivedHttpError(view, request, errorResponse);
// 这个方法在6.0才出现
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int statusCode = 0;
if (errorResponse != null) {
statusCode = errorResponse.getStatusCode();
}
Log.d(TAG, "onReceivedHttpError---> code = " + statusCode);
if (404 == statusCode || 500 == statusCode) {
view.loadUrl("about:blank");// 避免出现默认的错误界面
// 在这里可以考虑显示自定义错误页
// showErrorPage();
}
}
}
}
还有如下方法,在使用时尤其要注意:
1、重定向问题
在 shouldOverrideUrlLoading 方法可进行重定向的判断跟处理:
//Android7.0之后的方法
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Log.d(TAG, "shouldOverrideUrlLoading new---> url:" + request.getUrl());
analysisRequest(request);
String url = (request.getUrl()).toString();
boolean hasGesture = request.hasGesture();
boolean isRedirect = request.isRedirect();
return shouldOverride(view, url);
}
其WebView重定向需要考虑的case如下:
1、是最普通的http url【不含.doc .apk等下载url】
2、下载的http url【如.doc .apk等】
3、非http或https自定义url 【如 "weixin:// alipays://等】
【deprecated】如果期望打开web页时不自动唤起app,可通过 request.hasGesture()【是否】点击来判断,如果是true才唤起第三方app。(此种方案有时不太准确,故可采用下面方案)
【recommend】定义一个boolean值如:isClickWeb = false,在onTouchEvent DOWN方法中,将其赋值为true。在必要位置添加判断即可【具体可参考代码】
private boolean shouldOverride(WebView view, final String url) {
//业务需要可做处理
redirectionJudge(view, url);
if (SchemeUtil.isHttpProtocol(url) && !SchemeUtil.isDownloadFile(url)) {
return false;
}
if (SchemeUtil.isHttpProtocol(url) && SchemeUtil.isDownloadFile(url)) {
if (isClickWeb) {
openDialog(url);
return true;
}
}
if (!SchemeUtil.isHttpProtocol(url)) {
boolean isValid = SchemeUtil.isSchemeValid(context, url);
if (isValid && isClickWeb) {
openDialog(url);
} else {
Log.d(TAG, "此scheme无效[比如手机中未安装该app]");
}
return true;
}
return false;
}
2、实现预加载
在 shouldInterceptRequest 方法中可实现资源预加载:
@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
if (request == null) {
return null;
}
String url = request.getUrl().toString();
Log.d(TAG, "shouldInterceptRequest---> " + url);
return getWebResourceResponse(url);
}
protected WebResourceResponse getWebResourceResponse(String url) {
//此处[tag]等需要跟服务端协商好,再处理
if (url.contains("[tag]")) {
try {
String localPath = url.replaceFirst("^http.*[tag]\\]", "");
InputStream is = getContext().getAssets().open(localPath);
Log.d(TAG, "shouldInterceptRequest: localPath " + localPath);
String mimeType = "text/javascript";
if (localPath.endsWith("css")) {
mimeType = "text/css";
}
return new WebResourceResponse(mimeType, "UTF-8", is);
} catch (IOException e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
}
3、增加错误页面展示限制
在onReceivedError方法中,通过 request.isForMainFrame() || url.equals(getUrl() 判断来尽可能少的减少错误页面的展示。即当错误页面是主页面时才展示错误页,避免整个页面中如某个icon等展示错误,导致影响整个页面的情况【如网易音乐的某些URL,就曾有出现这种情况,通过这种方式可以避免错误页面展示】。
//Android6.0之后的方法
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String url = request.getUrl().toString();
int errorCode = error.getErrorCode();
String description = error.getDescription().toString();
Log.d(TAG, "onReceivedError---> " + " url:" + url + "errorCode:" + errorCode + " description:" + description + " failingUrl:" + url + " request.isForMainFrame():" + request.isForMainFrame());
// 如果当前网络请求是为main frame创建的,则显示错误页
if (request.isForMainFrame() || url.equals(getUrl())) {
showReceivedErrorPage(view, error.getErrorCode(), error.getDescription().toString(), request.getUrl().toString());
}
}
}
4、解决页面白屏问题
当SSL证书无效时,会导致白屏问题,可在 onReceivedSslError 方法中添加 handler.proceed();
可解决白屏问题:
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
//此处处理可避免SSL证书无效的页面白屏
handler.proceed();
super.onReceivedSslError(view, handler, error);
Log.d(TAG, "onReceivedSslError---> error = " + error);
}
以上就是Android WebView基础应用详解的详细内容,更多关于Android WebView的资料请关注编程网其它相关文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341