今天来说一下我在毕业设计开发时遇到的一个问题。我开发的是一个基于Android WebView手机浏览器。网上说WebView有不少坑,在实际开发时发现确实有不少坑。我遇到的其中一个问题出现在浏览器的前进后退功能上。首先出现的情况是网页因重定向无法正常调用WebView的goBack()方法,这个在网上已有不少解答了。然而网上的解决方法在我测试的Android 4.4手机上仍会出现问题,具体表现就是goBack()方法没有任何反应。所以只能采取自定义历史栈的方法。定义一个后退栈mBrowsedHistory和一个前进栈mForwardHistory,当访问一个网页时,将网页URL添加到后退栈中。执行后退时,后退栈弹出此URL,并同时在前进栈中加入此URL。当通过点击网站上的超链接访问网页时,前进栈会被清空。因刷新、重定向等载入的网页不会加入后退栈中。

例如,先访问A页面,再从A页面访问B页面后,此时后退栈为A、B,前进栈为空。从B页面后退至A页面,此时后退栈为A,前进栈为B。从A页面访问C页面,此时后退栈为A、C,前进栈置空。访问A页面,A页面加载时重定向为B页面,则只有B页面进入后退栈。

public void goBack() {
    if (mMainView != null) {
        mForwardHistory.push(mBrowsedHistory.peek());
        mBrowsedHistory.pop();
        mMainView.loadUrl(mBrowsedHistory.peek());
    }
}

public void goForward() {
    if (mMainView != null) {
        mMainView.loadUrl(mForwardHistory.peek());
        mBrowsedHistory.push(mForwardHistory.peek());
        mForwardHistory.pop();
    }
}

自定义历史栈后出现一个问题,原来goBack()和goForward()函数执行后不会重载后退/前进后的页面,但两个函数重写后,由于使用WebView的loadUrl方法,页面会重载。关于此问题,我参考了其他基于Android WebView的浏览器,发现Via浏览器有实现返回不重载的功能。我猜测它可能使用了单标签页多WebView的形式,也就是说每个网页都对应一个WebView,返回/前进时切换WebView。但由于开发时间有限,我的项目没法在短时间内换成这种形式,所以也就作罢。

参考资料: https://blog.csdn.net/t12x3456/article/details/39134961 https://juejin.im/post/5a5d8ef2f265da3e393a6b76