Android WebView 因重新導向無法正常goBack()解決方案
Android WebView 因重新導向無法正常goBack()解決方案
首先說下問題,初始頁面為A,點擊某個連結跳轉到B(http://xxx.com.cn/),B頁面重新導向到C頁面(http://xxx.com.cn/website/index.html)
當調用webview.goBack()時,頁面回退到B,然後接著會重新導向回C頁面.
這樣會導致兩個問題:
1. 無法回退到webview的初始頁面A
2. 無法正常退出Activity或者Fragment(只有還未載入完C時進行回退才能退出頁面)
關於如何解決這個問題,我總結了如下三種方法,可以根據具體情況進行使用:
一. 首先需要和前端開發人員溝通,看重新導向是否必要,如果跳轉連結只是網域名稱,然後預設重新導向到 網域名稱/index.html,並沒有特殊處理的話,那麼這種重新導向並沒有意義.
只要將網頁中的串連,比如
直接替換為
即可解決該問題.
二.頁面中的重新導向是必須的,那麼我們就需要自己維護一個webview的曆史棧,根據自己的需求進行過濾跳轉或者重新載入頁面:
判斷到當前為重新導向後的連結,那麼那麼當回退的時候就需要忽略上一級的連結,不使用webview.goback(),移除重新導向和重新導向後的url,
擷取到初始頁面連結後自己進行loadUrl()操作.
3.還有一種方法,和方法2類似,需要自己維護webview的曆史棧,但是需要前端的配合,提供js函數擷取網頁是否進行重新導向
在webviewClient回調shouldoverloading()中過濾url時,若屬於重新導向的地址,則不加入棧中,回退時根據曆史棧載入即可.
這裡主要講一下方法二:
首先定義一個曆史棧 :
private ArrayList loadHistoryUrls = new ArrayList();
把初始頁面Url加入
loadHistoryUrls.add(INITAL_WEB_URL);
然後加入載入的url:
public boolean shouldOverrideUrlLoading(WebView view,String url){ //將過濾到的url加入曆史棧中 loadHistoryUrls.add(url); return true; }
最後在webview.goback()處理:
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { //判斷是否可以返回操作 if (webView.canGoBack() && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { //過濾是否為重新導向後的連結 if(loadHistoryUrls.size()>0&&loadUrls.get(loadHistoryUrls.size()-1).contains("index.html")) //移除載入棧中的最後兩個連結 loadHistoryUrls.remove(loadHistoryUrls.get(loadHistoryUrls.size()-1)); loadHistoryUrls.remove(loadHistoryUrls.get(loadHistoryUrls.size()-1)); //載入重新導向之前的頁 webview.load(loadUrls.get(loadHistoryUrls.size()-1)); return true; } } }
關於載入棧,後來發現webview本身也有對應的API:
//擷取曆史列表 WebBackForwardList mWebBackForwardList = webView.copyBackForwardList();
不過這個api可能受系統版本的影響或者不同手機系統進行了修改
所以解決該問題時,大家可以自己根據需求,自己維護載入的曆史棧或者直接調用系統api.
這裡總結一下,若重新導向非必要,採取方案一,最簡單,修改量也非常小. 重新導向必要,則使用方式情節二或者方案三.
因為需要和前端人員互動,方案三所需要的溝通,開發,維護的成本要比方案二高出不少,但對於是否重新導向的判斷非常準確,若有多個重新導向的情況,一次開發完成後不需要對代碼再次改動. 方案二則需要寫死需要過濾的url,若出現多個重新導向,則會顯得代碼比較臃腫,每次都需要重新增加代碼. 具體使用依據項目中的開發情況而定.
如有轉載,請聲明出處: 時之沙: http://blog.csdn.net/t12x3456