如何控制Android WebView历史/后台堆栈?

Pau*_*ean 9 android

我试图找到一种方法来处理WebView后台堆栈,类似于Android Web浏览器在我自己的应用程序的WebView中按下后退按钮时如何处理它.

问题与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);
}
Run Code Online (Sandbox Code Playgroud)

如您所见,按后退按钮可选择堆栈中的先前URL,该URL在调用shouldOverrideUrlLoading()之后加载到WebView本身.我实际上在shouldOverrideUrlLoading()中做了很多与这个特定问题无关的事情,所以"删除我的WebViewClient实现"对我来说不起作用.无论如何,当前一个URL是Javascript重定向时,该URL加载,然后Javascript立即重定向到WebView所在的URL.我无法禁用Javascript,因为网站依赖于它.我也无法更改网站(第三方).

这种重定向问题的结果是最终用户的恶性循环,他们疯狂地回击只是比Android网页处理引擎稍快.

现在这里有趣的地方:Android网页浏览器处理后退按钮就好了Javascript重定向!它遵循重定向很好,但后退按钮执行用户期望它做的事情.这意味着可以正确处理这种情况.Android Web浏览器如何处理此问题?

小智 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);
   }
Run Code Online (Sandbox Code Playgroud)

这里myWebView在Activity的onCreate中声明


sih*_*hrc 6

检测用户何时触发了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();
    }
}
Run Code Online (Sandbox Code Playgroud)