一直都在做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;
}
}
}