在Android開發(fā)過程中,使用過WebView的童鞋可能難免會遇到URL重定向問題。
簡單敘述下這種問題的情況,就是WebView首先加載A鏈接,然后在WebView上點擊一個B鏈接進行加載,B鏈接會自動跳轉到C鏈接,這個時候調用WebView的goback方法,會返回到加載B鏈接,但是B鏈接又會跳轉到C鏈接,從而導致沒法返回到A鏈接界面(當然也有朋友說快速的按兩次返回鍵-也就是連續(xù)觸發(fā)了兩次goback可以返回到A鏈接,但并不是所有用戶都懂這個,而且操作上也很惡心。),這就是重定向問題。
這個問題由來已久,網上解決辦法也有好幾種,但是都沒有什么很好的統(tǒng)一的解決方式,QQ微信之類的內置瀏覽器做的很好,不過不知道其實現方式。
以往的解決思路就是包括自己維護webview的url歷史棧,或者前后端勾兌好,或者依賴服務器之類的什么沒試過的xx方式,見鏈接:
http://blog.csdn.net/t12x3456/article/details/39134961
內容就各位慢慢去體會,也是一種思考的過程,其實這些解決辦法在以往也是非常有用的,其實這個解決辦法跟工程設置的編譯版本和最小版本有關,大家都知道,在不同的版本上,程序有很多不同的效果和處理方式。今天我關注的不是在上面,而是接下來要說的4.0以后的解決重定向的方法,非常簡單(我是基于4.0做得測試,到底這個方法支持到什么版本,我未研究)。
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
});
一言不合就貼了代碼,對的,就是這么簡單,就是直接返回false,就可以解決重定向問題。
網上搜索了下這里返回false和返回true的原因,其實我也看的云里霧里,沒理解透徹
shouldOverrideUrlLoading :這個方法的返回值
return true 表示當前url即使是重定向url也不會再執(zhí)行(除了在return true之前使用webview.loadUrl(url)除外,因為這個會重新加載)
return false? 表示由系統(tǒng)執(zhí)行url,直到不再執(zhí)行此方法,即加載完重定向的ur(即具體的url,不再有重定向)。
先弄出來,大家可以交流,看看對不同的api的效果是什么樣子。
附帶在一個論壇上看到一個網友的解釋,我覺得也很有參考的價值,其實跟自己維護歷史棧道理相同,不過它是通過httpcode來判斷是否是重定向地址,以下是他說的:
來講講WebView加載重定向頁面會遇到問題。
1.如果需要獲取webview訪問的url地址,那么加載重定向頁面時會顯示兩次
2.如果WebView在加載頁面的過程中,有加載重定向頁面,那么在Android2.3版本中會遇到無法回退的問題,但是4.0以上系統(tǒng)不會。例如,用戶在點擊回退時,webview會執(zhí)行goBack()方法,2.3系統(tǒng)不能正常回退,而4.0能正常回退,可以解釋為4.0系統(tǒng)的webview對重定向做了處理,他會把重定向的兩個頁面看做是一個頁面,所以webview成功回退了,但是2.3系統(tǒng)的webview會先回退到重定向頁面(非真正的目的頁面),回退之后會執(zhí)行l(wèi)oadUrl(url)方法,而這是因為url是個重定向url,所以會跳轉到真正的目標頁面,so,經過兩次加載,頁面還是回到goBack()之前的頁面!
問題2的解決方案:
從重定向的概念可知,當訪問重定向url時服務器會返回301狀態(tài)碼,那么可以根據此特殊的狀態(tài)碼來把重定向頁面排除在歷史訪問記錄隊列里。
具體思路為:
(1)自定義一個歷史url訪問隊列——MyWebBackForwardList
(2)在webview每次loadUrl(url)之前先用HttpUrlConnection對象的getResponseCode()方法來獲取狀態(tài)碼,如果==301,不加入隊列中,否者加入。
(3)重寫webview的canGoBack()和goBack()方法
不再使用webview的WebBackForwardList對象來取歷史url,而是使用自定義的MyWebBackForwardList來取出回退的url