13

自分のアプリの 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);
}

ご覧のとおり、戻るボタンを押すとスタック内の前の URL が選択され、shouldOverrideUrlLoading() が呼び出された後に WebView 自体に読み込まれます。私は実際に shouldOverrideUrlLoading() 内でこの特定の質問に関係のない多くのことを行っているため、「WebViewClient 実装を削除する」は機能しません。とにかく、前の URL が Javascript リダイレクトの場合、その URL が読み込まれ、Javascript はすぐに WebView があった URL にリダイレクトされます。Web サイトが Javascript に依存しているため、Javascript を無効にできません。また、Web サイト (サードパーティ) を変更することもできません。

このリダイレクトの問題の結果は、Android Web ページ処理エンジンよりもわずかに高速であることだけを必死に要求しているエンドユーザーにとって悪循環です。

ここからが興味深いところです。Android Web ブラウザーは、Javascript リダイレクトの戻るボタンを問題なく処理します。リダイレクトには問題なく従いますが、戻るボタンはユーザーが期待することを行います。つまり、このシナリオを正しく処理できるということです。Android Web ブラウザはこの問題をどのように処理しますか?

4

7 に答える 7

9

ユーザーによって URL の読み込みがトリガーされたときを検出し、代わりにそれらをバックスタックに追加します。

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();
    }
}
于 2014-06-12T16:56:45.983 に答える
1

私はあなたと同様の問題を抱えていて、それを理解する方法を見つけました。これが私の答えです。

最初のリンク (www.new.a) をクリックすると、他のリンク (mobile.new.a) に自動的にリダイレクトされます。通常、リンクは 2 つまたは 3 つのリダイレクトを行いますが、私のソリューションはほぼすべてのリダイレクト リンクで機能しています。この回答が、リンクのリダイレクトに役立つことを願っています。

私はついにそれを理解しました。4 つの API を持つ WebViewClient が必要です。WebViewClient には shouldOverrideUrlLoading()、onPageStarted()、onPageFinished()、および doUpdateVisitedHistory() があります。必要な API はすべて API 1 であるため、心配する必要はありません。

これが私の答えです。それをチェックしてください!:)

于 2014-07-23T01:33:35.777 に答える
0

このスニペットは私にとってはうまくいきます、試してみてください:

@Override
public void onBackPressed() {
    BlankFragment fragment = (BlankFragment)
            getSupportFragmentManager().findFragmentByTag("webView");
    if (fragment.canGoBack()) {
        fragment.goBack();
    } else {
        super.onBackPressed();
    }
  }
于 2016-09-09T14:13:11.897 に答える