WebView 加载https 白屏以及重定向加载

前言:

今天在处理app 内广告跳转的问题时候,遇到官网 公司官网 https 点击打不开的情况,因为公司官网在手机页面上会重定向到手机版的页面去,处理到最后发现是一个细节导致的,特地记录下解决过程。


1.针对正常的webView 加载内核:(参考摘录地址)
1-1. 启用mixed content

在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);
    }

1-2. 设置WebView接受所有网站的证书

在认证证书不被Android所接受的情况下,我们可以通过设置重写WebViewClient的onReceivedSslError方法在其中设置接受所有网站的证书来解决,具体代码如下:

//重写 onReceivedSslError 内的super 方法需要注释掉
mWebView.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView webView, String s) {
                super.onPageFinished(webView, s);
                Log.d(TAG,"setWebViewClient onPageFinished");
                topTitle.setText(webView.getTitle());
                closeLoadingAnimal();
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView webView, String url) {
                Log.d(TAG,"setWebViewClient shouldOverrideUrlLoading url="+url);
                if (StringUtil.isEmpty(url)) {
                    return false;
                }

                dealUrl(url);
                return true;
            }

            @Override
            public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) {
                Log.e(TAG,"onReceivedSslError sslError="+sslError.toString());
                if(sslError.getPrimaryError() == android.net.http.SslError.SSL_INVALID ){// 校验过程遇到了bug
                    sslErrorHandler.proceed();
                }else{
                    sslErrorHandler.cancel();
                }
            }

        });
2.针对腾讯TBS x5内核:

2-1.同样需要启用 mixed content,对于 html 页面内有https 和 http 图片混合的相关的连接地址,同样适用

引用x5 内核的相关引用
import com.tencent.smtt.export.external.interfaces.SslError;
import com.tencent.smtt.export.external.interfaces.SslErrorHandler;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;
settings.setMixedContentMode(WebSettings.LOAD_NORMAL);//处理http 和 https 图片混合的问题

2-2:设置WebView接受所有网站的证书

同上 1-2


3.处理重定向的问题:

注意:有些网页需要支持Dom 存储(可处理部分白屏的问题)

settings.setDomStorageEnabled(true);

按照API的说明  Sets whether the DOM storage API is enabled. The default value is false. 

也就是是否开启本地DOM存储。应该是Html 5中的localStorage(可以使用Android4.4手机和Chrome Inspcet Device联调),用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的,绝大多数的浏览器都是支持 localStorage 的,但是鉴于它的安全特性(任何人都能读取到它,尽管有相应的限制,将敏感数据存储在这里依然不是明智之举),Android 默认是关闭该功能的。



因为页面内部,有图片地址连接 ,股票连接,等等,所有对相关的地址进行了拦截,我犯的错误是 重定向后显示的新连接 我没有进行处理。所以显示一直只加载中(白屏)。

对于 拦截到的url ,进行不同的处理,如果遇到重定向的页面特殊处理,我这里是重新跳转新的页面 

IntentUtils.toWebshell(BaseDetailsWebviewActivity.this, url);

如果是当前页面 webView.load(url);也可以,针对不同情况自行处理.

@Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) { // 网页超链点击处理
                Log.e("baseWebDetail", "shouldOverrideUrlLoading url " + url+"\n");
                if (url == null) {
                    return false;
                }

                //判断重定向的方式一
                WebView.HitTestResult hitTestResult = view.getHitTestResult();

                if (url.startsWith("tel") || url.startsWith("mailto") || url.endsWith(".apk") || url.endsWith(".download")) {
                    dealApplicationUrl(url);
                } else if (url.startsWith("xxx://")) {
                    dealSchemaUrl(url);
                } else if (url.startsWith("xxx://")) {
                    dealWebFontUrl(url);
                } else if (url.startsWith("xxx://imgclick")) {
                    showBigImages(url);
                } else if (url.contains("/stock/xxx/")) {
                    dealStockUrl(url);
                } else {
                    isRedirect = false;
                    //重定向判断
                    if(hitTestResult.getType() == WebView.HitTestResult.UNKNOWN_TYPE) {
                        share.setVisibility(View.VISIBLE);
                        collection.setVisibility(View.VISIBLE);
                        mCommentLayout.setVisibility(View.GONE);
                        isRedirect = true;
                        return false;
                    }

                    IntentUtils.toWebshell(BaseDetailsWebviewActivity.this, url);
                }
                return true;
            }


结束语:把webView 加载url 的逻辑梳理一遍,发现是拦截后的url ,没有处理。坑爹啊。。。,所以遇到问题先把 相关逻辑梳理清楚,确保手机端 处理是没有问题,再去找web端或者后端 联调处理。最后,好久没写博客了,博客的新版还是挺方便的,但是我更喜欢markdown 哈哈哈哈哈哈哈!

what! 新版编辑器 发的代码格式 和样式怎么这么丑。。。以后还是用 markdown 吧!


你可能感兴趣的:(android-杂记)