如何控制Android WebView的历史/回栈?

我试图找出一种方法来处理WebView返回堆栈,类似于Android Web浏览器在从我自己的应用程序的WebView中按下后退button时处理它的方式。

这个问题与Javascriptredirect有关 。 WebView返回堆栈似乎包含简单redirect的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); } 

如您所见,按下后退button将select堆栈中的前一个URL,在调用shouldOverrideUrlLoading()之后,将在WebView中加载该URL。 我实际上做了更多的内部shouldOverrideUrlLoading()这是不相关的这个特定的问题,所以“删除我的WebViewClient实现”将不适用于我。 无论如何,当前一个URL是一个Javascriptredirect时,该URL将被加载,然后Javascript会立即redirect到WebView刚才的URL。 我无法禁用Javascript,因为网站取决于它。 我也不能改变网站(第三方)。

这个redirect问题的结果是一个恶性循环,最终用户疯狂地压倒比Android网页处理引擎略快。

现在,这里是它变得有趣的地方:Android的网页浏览器处理返回button就好了Javascriptredirect! 它遵循redirect就好,但后退button做用户期望它做。 这意味着可以正确处理这种情况。 Android网页浏览器如何处理这个问题?

Solutions Collecting From Web of "如何控制Android WebView的历史/回栈?"

你的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中声明的

当用户触发url加载时检测,并将其添加到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(); } } 

我和你有类似的问题,并find了解决办法。 这是我的答案 。

当我点击第一个链接(www.new.a)时,它会自动redirect其他链接(mobile.new.a)。 通常链接redirect两个或三个,我的解决scheme已在几乎每个redirect链接工作。 我希望这个答案帮助你与annyoingredirect链接。

我终于明白了这一点。 您需要一个带有四个API的WebViewClient。 在WebViewClient中,有onOverrideUrlLoading(),onPageStarted(),onPageFinished()和doUpdateVisitedHistory()。 所有你需要的API是API 1,所以不用担心。

这是我的答案 。 看看! 🙂

 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(); } } 

正确的答案是按照https://stackoverflow.com/a/8644978/5022858和https://developer.android.com/reference/android/webkit/WebViewClient.html中所述&#x5728;shouldOverrideUrlLoading()上返回false 。 这可以防止redirect被添加到历史logging列表中。