一直都在做HTML與原生混合式開發,前面遇到一個問題,我們的合作企業,合入我們的APP之後,出現頁面跳轉頁面死循環的問題。
1.下面是我們APP裝載HTML後頁面的邏輯||原理
這裏把
合作公司的HTML簡稱[yiju_html],
我們裝載的webview中的html叫做 [webview_html]
合作公司的返回前面一個頁面叫做 yiju_back()
我們app中的返回圖標原生[webview_back()]
html history 返回簽名一個頁面繼history.back(-1) || history.go(-1)簡稱[back()]
這樣我們就有了如下的邏輯
如果沒有重定向,就有
if(yiju_back()==back()){
webview_back()=yiju_back()=back();
//這是一種完全按照history來的
}else{
webview_back()=back();
yiju_back()!=back();
//這裏合作公司的跳轉就完全按照自己的邏輯走了
//但是自己的返回button處理就按照歷史記錄history處理
}
當然現在很多的大的企業還是,按照很嚴格的history的處理的,但是也不乏有重定向的出現如何處理呢
2.什麼是HTML重定向
應爲本人對於定義的理解還是很模糊的,顧save了下,html重定向的定義,下面的定義來自於百度詞條
html重定向就是通過各種的方法將各種網絡請求重新定個方向轉到其它位置。 在網站建設中,時常會遇到需要網頁重定向的情況:象網站調整,如改變網頁目錄結構,網頁被移到一個新地址,再或者,網頁擴展名改變,如因應用需要把。php改成。Html或。shtml,在這種情況下,如果不做重定向,則用戶收藏夾或搜索引擎數據庫中舊地址只能讓訪問客戶還會得到一個404頁面錯誤信息,訪問流量白白喪失;再如某些註冊了多個域名的網站,也需要通過重定向讓訪問這些域名的用戶自動跳轉到主站點,等等。
3.正常打開 和非正常打開跳轉頁面日誌分析
更具仔細研究重定向和非重定向頁面的跳轉,發現,問題所在,在於重定向的頁面,點擊返回按鈕之後,非重定向頁面會再次加載一次,顧出現多次調用,變成死循環
4.如何解決3的問題
根據,上條的分析,我們知道需要避免的就是加載重定向頁面之後,費重定向頁面重新加載,顧需要避免,顧有了下面的邏輯
1)定義一個集合用來裝載跳轉歷史url
2)url加入集合,記錄非重定向鏈接, 避免刷新HTML引發多次加入集合,和獲取到的goLastPage()錯誤
3)url加入集合,記錄重定向鏈接,重定向鏈接和之前頁面一定不同,顧加入集合數據
4)返回方法,獲取簽名一個頁面,並且加載url
這裏相當於自己記載了頁面跳轉邏輯,通過自己的記錄數據,進行跳轉頁面,從而達到頁面跳轉正常
5.代碼實現
package 包名;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.ali.auth.third.core.util.StringUtil;
import com.reach.doooly.R;
import java.util.Stack;
public class TestActivity extends AppCompatActivity {
private WebView webview;
private MyWebViewClient webViewClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview_layout);
webview = (WebView) findViewById(R.id.view_webview);
webViewClient = new MyWebViewClient();
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebViewClient(webViewClient);
webview.loadUrl("地址");
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return pageGoBack(webview,webViewClient);
}
public boolean pageGoBack(WebView web, MyWebViewClient client) {
final String url = client.popLastPageUrl();
if (url != null) {
web.loadUrl(url);
return true;
}
finish();
return false;
}
class MyWebViewClient extends WebViewClient {
/**
* 記錄URL的棧
*/
private final Stack<String> mUrls = new Stack<>();
/**
* 判斷頁面是否加載完成
*/
private boolean mIsLoading;
private String mUrlBeforeRedirect;
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (mIsLoading && mUrls.size() > 0) {
mUrlBeforeRedirect = mUrls.pop();
}
recordUrl(url);
this.mIsLoading = true;
}
/**
* 記錄非重定向鏈接, 避免刷新頁面造成的重複入棧
*
* @param url 鏈接
*/
private void recordUrl(String url) {
//這裏還可以根據自身業務來屏蔽一些鏈接被放入URL棧
if (!StringUtil.isEmpty(url) && !url.equalsIgnoreCase(getLastPageUrl())) {
mUrls.push(url);
} else if (!StringUtil.isEmpty(mUrlBeforeRedirect)) {
mUrls.push(mUrlBeforeRedirect);
mUrlBeforeRedirect = null;
}
}
/**
* 獲取上一頁的鏈接
**/
private synchronized String getLastPageUrl() {
return mUrls.size() > 0 ? mUrls.peek() : null;
}
/**
* 推出上一頁鏈接
*/
public String popLastPageUrl() {
if (mUrls.size() >= 2) {
mUrls.pop(); //當前url
return mUrls.pop();
}
return null;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (this.mIsLoading) {
this.mIsLoading = false;
}
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
}
}