1

In my app there is a WebView displaying Html content and a back button to let the user navigate back in the browser history. In the WebChromeClient, I get the Html page title in onReceivedTitle() and display it in my app.

The user is shown the first page and the first page title is displayed. The user can then click a hyperlink in the Html to get to the next page. The second page has a different title, and this is correctly displayed. The problem is if the user than clicks the Back button, the first page is diaplayed from the history but onReceivedTitle() is not called again. So my fist page is displayed with the wrong title from the second page.

How can I get the title of the page being that was loaded by the call to goBack()?

Here is some simplified code to demonstrate. Imagine a layout with a TextView, WebView, and Button. Also, imagine two Html files in the assets folder where pageone.html links to pagetwo.html and the two pages have different titles.

public class MyActivity extends Activity {
    WebView webView;
    TextView title;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        webView = (WebView) findViewById(R.id.webView);
        title = (TextView) findViewById(R.id.title);
        webView.loadUrl("file:///android_asset/pageone.html");

        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onReceivedTitle(WebView view, String titleText) {
                super.onReceivedTitle(view, titleText);
                title.setText(String.format("Title: %s", titleText));
            }
        });

        final Button button = (Button) findViewById(R.id.backButton);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if (webView.canGoBack()) {
                    webView.goBack();
                }
            }
        });
    }

}
Michael Levy
  • 13,097
  • 15
  • 66
  • 100

1 Answers1

1

Apparently, this is a bug in certain builds of Android and used to work correctly.


I had been using the suggestion from https://stackoverflow.com/a/12154530/90236, but I think the answer for me is to not use onReceivedTitle() because it isn't called after a goBack.

onPageFinished() in the WebViewClient seems to be better if you need to handle goBack().

This seems to be working:

public class MyActivity extends Activity {
    WebView webView;
    TextView title;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        webView = (WebView) findViewById(R.id.webView);
        title = (TextView) findViewById(R.id.title);
        webView.loadUrl("file:///android_asset/pageone.html");

        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                title.setText(String.format("Title: %s", view.getTitle()));
            }
        });

        final Button button = (Button) findViewById(R.id.backButton);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if (webView.canGoBack()) {
                    webView.goBack();
                }
            }
        });
    }

}

However, this changes the timing of when the Android app is notified of the title. What I have found is:

  1. WebChromeClient.onReceivedTitle occurs first. However, this event does not occur when webView.goBack() is used to navigate to a page.
  2. Then the html page loads and the DOM window.onload occurs
  3. Finally WebViewClient.onPageFinished occurs

If you use Javascript to update the page title, using onPageFinished may have quite different behavior than onReceivedTitle because of the event timing.

Community
  • 1
  • 1
Michael Levy
  • 13,097
  • 15
  • 66
  • 100