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 吧!