我正在尝试找出一种处理WebView后台堆栈的方法,类似于在我自己的应用程序的WebView中按下后退按钮时Android Web浏览器如何处理它。
问题与 Javascript重定向有关。 WebView后备堆栈似乎包含只是重定向的URL。这是我的相关代码:
private class ArticleWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK)
{
WebView wv = (WebView)findViewById(R.id.web);
if (wv.canGoBack())
{
wv.goBack();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
如您所见,按后退按钮可选择堆栈中的上一个URL,该URL在调用shouldOverrideUrlLoading()之后加载到WebView本身。我实际上在shouldOverrideUrlLoading()中做了很多与这个特定问题无关的事情,所以“删除我的WebViewClient实现”对我来说不起作用。无论如何,当前一个URL是Javascript重定向时,该URL加载,然后Javascript立即重定向到WebView所在的URL。我无法禁用Javascript,因为网站依赖于它。我也无法更改网站(第三方)。
此重定向问题的结果是最终用户的恶性循环,他们疯狂地回击只是为了比Android网页处理引擎稍快。
现在这里有趣的地方:Android网页浏览器处理后退按钮就好了Javascript重定向!它遵循重定向很好,但后退按钮执行用户期望它做的事情。这意味着可以正确处理这种情况。 Android Web浏览器如何处理此问题?
答案 0 :(得分:6)
你的onKeyDown应该看起来像这些
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
myWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
这里myWebView在Activity的onCreate
中声明答案 1 :(得分:6)
检测用户是否触发了网址加载,然后将其添加到Backstack中。
private List<String> previous = new ArrayList<String>();
private String mLastUrl;
webview.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
Log.i("DebugDebug", "OnPageFinished " + url);
mLastUrl = url;
super.onPageFinished(view, url);
}
});
webview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
WebView.HitTestResult hr = ((WebView)view).getHitTestResult();
if (hr != null && mLastUrl != null) {
if (previous.isEmpty() || !previous.get(previous.size() - 1).equals(mLastUrl)) {
previous.add(mLastUrl);
}
Log.i("DebugDebug", "getExtra = " + hr.getExtra() + "\t\t Type = " + hr.getType());
}
return false;
}
});
@Override
public void onBackPressed() {
Log.i("DebugDebug", "onBackPressed");
int size = previous.size();
if (size > 0){
webview.loadUrl(previous.get(size - 1));
previous.remove(size - 1);
} else {
super.onBackPressed();
}
}
答案 2 :(得分:1)
我和你的问题有类似的问题,并找到了解决问题的方法。这是my answer。
当我点击第一个链接(www.new.a)时,它会自动重定向其他链接(mobile.new.a)。通常链接重定向两个或三个,我的解决方案几乎在每个重定向链接上都有效。我希望这个答案可以帮助你改进重定向链接。
我终于明白了。您需要一个包含四个API的WebViewClient。 WebViewClient中有shouldOverrideUrlLoading(),onPageStarted(),onPageFinished()和doUpdateVisitedHistory()。您需要的所有API都是API 1,所以不要担心。
这是my answer。看看那个! :)
答案 3 :(得分:0)
this snippet work for me, try this.
@Override
public void onBackPressed() {
BlankFragment fragment = (BlankFragment)
getSupportFragmentManager().findFragmentByTag("webView");
if (fragment.canGoBack()) {
fragment.goBack();
} else {
super.onBackPressed();
}
}
答案 4 :(得分:0)
正确的答案是按https://stackoverflow.com/a/8644978/5022858和https://developer.android.com/reference/android/webkit/WebViewClient.html中的说明在false
上返回shouldOverrideUrlLoading()
。这可以防止重定向添加到历史列表中。
答案 5 :(得分:0)
private class ArticleWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK)
{
WebView wv = (WebView)findViewById(R.id.web);
if (wv.canGoBack())
{
wv.goBack();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
如果你想在webview而不是系统浏览器中处理链接,这个shouldOverrideUrlLoading
方法返回 false
,并且不要拨打view.loadUrl(url)
,你的如果您返回false,webview将自动加载网址。如果您手动加载网址,则历史记录将不正确。
答案 6 :(得分:0)
boolean isGoBack = false; //back key is pressed
private long goBackTime = 0; //
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
isGoBack = true;
goBackTime = System.currentTimeMillis();
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
Webview mWebView.
setWebViewClient(new WebViewClient() { //setWebViewClient
@Override
public boolean shouldOverrideUrlLoading (WebView view, String url){
if (!TextUtils.isEmpty(startUrl) && !startUrl.equals(url) && isGoBack && System.currentTimeMillis() - goBackTime < 600) {
isGoBack = false;
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
finish(); //activity finish
}
} else {
view.loadUrl(url);
isGoBack = false;
return true;
}
return false;
}
@Override
public void onPageStarted (WebView view, String url, Bitmap favicon){
super.onPageStarted(view, url, favicon);
startUrl = url;
}
}