Android webview加载https链接错误或无响应的解决
作者:想你依然心痛
最近做无线WiFi的时候,在最后认证成功的时候会弹出一个广告页,于是用webview去加载了一下,结果没反应,打印url出来看了一下,发现是https格式的,在使用WebView加载https资源文件时,如果认证证书不被Android认可,那么会出现无法成功加载对应资源问题。那么,我们就要针对这一状况作出对应的处理。
于是百度了一下,这里记录一下,给大家做个参考:
1、设置WebView接受所有网站的证书
在认证证书不被Android所接受的情况下,我们可以通过设置重写WebViewClient的onReceivedSslError方法在其中设置接受所有网站的证书来解决,重写WebView的onReceivedSslError方法,添加handler.proceed方法,但App如果上架GooglePlay会被警告的。所以建议使用以下的第二个方法。
具体代码如下:
webView.setWebViewClient(new WebViewClient(){ @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){ handler.proceed(); } });
注:在重写WebViewClient的onReceivedSslError方法时,注意一定要去除onReceivedSslError方法的super.onReceivedSslError(view, handler, error);,否则设置无效。
2、启用mixed content
Android webView 从 Lollipop 开始默认不开MixedContentMode,因此,我们开启即可满足我们大多数需求。
webView.setWebViewClient(new WebViewClient(){ @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webView.getSettings() .setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); } });
在Android5.0中,WebView方面做了些修改,如果你的系统target api为21以上:
系统默认禁止了mixed content和第三方cookie。可以使用setMixedContentMode() 和 setAcceptThirdPartyCookies()以分别启用。
系统现在可以智能选择HTML文档的portion来绘制。这种新特性可以减少内存footprint并改进性能。若要一次性渲染整个HTML文档,可以调用这个方法enableSlowWholeDocumentDraw(),如果你的app的target api低于21:系统允许mixed content和第三方cookie,并且总是一次性渲染整个HTML文档。
在使用WebView的类中添加如下代码:
// android 5.0以上默认不支持Mixed Content if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webView.getSettings().setMixedContentMode( WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE); }
结果:
我的问题并不是出现在这些地方,而是出现了在加载Url时,部分Url使用的事http而不是https,导致无法加载,功能实现不了。那么要求后台开发人员把http改成https。就这样,成功了。或者还可以使用一些第三方库来加载也行。
测试:
1、调用高德地图没法显示,前端工程师用了http……那么改为https
2、部分功能没实现,因为后台的没有加证书…..那么,全部改回http
补充知识:Android WebView加载网页链接遇到的那些坑
本来觉得十分简单的问题,结果遇到了不少坑,到现在都不敢保证不出问题,只是解决了大部分问题。。。
下面是列出几个问题
在webview中跳转别的页面无响应
在webview中下载文件无响应
部分网址链接无法显示
部分网址打开自动跳转到浏览器
1.在webview中跳转别的页面无响应
修改之前代码如下:
WebSettings webSettings = webView.getSettings(); //设置WebView属性,能够执行Javascript脚本 webSettings.setJavaScriptEnabled(true); //设置可以访问文件 webSettings.setAllowFileAccess(true); //设置支持缩放 webSettings.setBuiltInZoomControls(true); webView.loadUrl(link); webView.setWebViewClient(new webViewClient ());
修改之后加了不少webview的设置包括:
webSettings.setAppCacheEnabled(true); webSettings.setDomStorageEnabled(true); webSettings.supportMultipleWindows(); webSettings.setAllowContentAccess(true); webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); webSettings.setUseWideViewPort(true); webSettings.setLoadWithOverviewMode(true); webSettings.setSavePassword(true); webSettings.setSaveFormData(true); webSettings.setJavaScriptCanOpenWindowsAutomatically(true); webSettings.setLoadsImagesAutomatically(true); webView.setWebChromeClient(new WebChromeClient());//这行最好不要丢掉
当然,这些属性可能有些不是必须要添加的,为了尽量满足多种需求,所以我都添加了。
修改完成后就可以在webview中跳转别的url链接了,就算是解决了第一个问题吧。
2.在webview中下载文件无响应
因为本身webview不具备下载功能,所以需要让系统处理或者自定义下载。
webview给我们提供了一个下载监听接口,下面我们来实现下载处理:
class MyDownLoad implements DownloadListener { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { if (url.endsWith(".apk")) { /** * 通过系统下载apk */ Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW,uri); startActivity(intent); } } }
然后再设置中添加:
webView.setDownloadListener(new MyDownLoad());
这里是将下载功能交给系统来处理了,并没有特殊需求所以就不自定义了。
3.部分网址链接无法显示,报错net::err_unknown_url_scheme
由于我们有时候自定义了WebViewClient,内容大致如下:
private class webViewClient extends WebViewClient { public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadurl(url)//返回true代表在当前webview中打开,返回false表示打开浏览器 return super.shouldOverrideUrlLoading(view,url); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { if(!dialog.isShowing()) { dialog.show(); } super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { if(dialog.isShowing()){ dialog.dismiss(); } super.onPageFinished(view, url); } }
注意shouldOverrideUrlLoading方法,平时我们可能会在其中设置view.loadurl(url),正是这句代码导致部分网页打不开,这可能是webview的本身加载网页有限制吧。所以我把这句去掉了,在返回时返回了true(true表示在当前webview中打开网页,false则更倾向于浏览器打开网页)。这样做,发现部分网页仍然打不开。于是直接删掉了webView.setWebViewClient(new webViewClient ()),而webView.setWebChromeClient(new WebChromeClient())不能删,结果网页是打开了,但有的则自动跳转到浏览器打开的。但我们的需求是不要打开浏览器。。。
4.部分网址打开自动跳转到浏览器
接到上面所讲,打开部分网址跳转到浏览器了,如何不让他跳转呢,返回true可以禁止跳转,但部分网址在webview中无法打开,接下来,不给它直接返回true或false了,而是返回super,让它父类处理,结果也并没有调到浏览器并且网页也打开了,现在暂时就这样结尾了做到了大部分网址的兼容。
总结:本人对webview了解也是有限,所以并不深入只是解决部分问题,可能理解也有偏差,如有问题请见谅。希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- Android okhttp的启动流程及源码解析
- Retrofit和OkHttp如何实现Android网络缓存
- Java/Android 实现简单的HTTP服务器
- Android Studio OkHttpClient使用教程详解
- Android :okhttp+Springmvc文件解析器实现android向服务器上传照片
- android 使用okhttp可能引发OOM的一个点
- Android Okhttp断点续传面试深入解析
- Android使用OkHttp发送post请求
- Android基于OkHttp实现下载和上传图片
- Android使用OkHttp进行重定向拦截处理的方法
- Android使用 Coroutine + Retrofit打造简单的HTTP请求库