Android WebViewClient callbacks called too often

12,431

Solution 1

This is a cross-post from a google groups discussion I started on the topic.

I've done more research, and I think I understand everything that's going on.

Here is my WebViewClient:

public class MyWebViewClient extends WebViewClient {
  @Override
  public void onPageStarted(WebView view, String url, Bitmap favicon) {
    System.out.println("onPageStarted: " + url);
  }

  @Override
  public boolean shouldOverrideUrlLoading(WebView webView, String url) {
    System.out.println("shouldOverrideUrlLoading: " + url);
    webView.loadUrl(url);
    return true;
  }

  @Override
  public void onPageFinished(WebView webView, String url) {
    System.out.println("onPageFinished: " + url);
  }
}

I have the following URL redirects from my server:

http://example.com/resource -> http://example.com/user-name/resource
http://example.com/logout.jsp -> http://example.com/login/logout
http://example.com/login/logout -> http://example.com/login

These URLs are part of a server that I don't control, so I just have to deal with the behavior.

Here is the output from loading http://example.com/resource

onPageStarted: http://example.com/resource
onPageStarted: http://example.com/user-name/resource
shouldOverrideUrlLoading: http://example.com/user-name/resource
onPageFinished: hhttp://example.com/user-name/resource

at this point, my WebView has blank content. I must wait until after the second onPageFinished to grab my content.

onPageStarted: http://example.coms/user-name/resource
onPageFinished: http://example.com/user-name/resource

Here is the output from loading http://example.com/logout.jsp

onPageStarted: http://example.com/logout.jsp
onPageStarted: http://example.com/login/logout
shouldOverrideUrlLoading: http://example.com/login/logout
onPageFinished: http://example.com/login/logout
onPageStarted: http://example.com/login/logout
onPageStarted: http://example.com/login
shouldOverrideUrlLoading: http://example.com/login
onPageFinished: http://example.com/login

again, at this point, my WebView has a blank page. I have to wait until the 3rd onPageFinished to get my content from the WebView.

onPageStarted: http://example.com/login
onPageFinished: http://example.com/login

Based on the documentation, I don't expect this behavior. Notice that there is an unbalanced number of onPageStarteds and onPageFinisheds. I especially dislike how onPageFinished gets called with my redirected URL, yet the WebView doesn't contain my content. I understand that this behavior is probably unchangeable, but this unexpected behavior should at least be documented.

Solution 2

@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
    System.out.println("shouldOverrideUrlLoading: " + url);
    return true;
}

You don't need to explicitly call webView.loadUrl(url). By overriding to return true will automatically get your existing webview to handle the new page load. By unnecessarily invoking that, it starts a brand new cycle of webpage load on that webView in the middle of the original cycles (onPageStarted -> onPageFinished) hence extra cycle of callback triggered in total.

Share:
12,431
user963601
Author by

user963601

I've been a professional software developer since 2002. Presented at StrangeLoop: http://www.infoq.com/presentations/Testing-Testing-iOS https://thestrangeloop.com/sessions/make-your-mobile-apps-accessible-to-all Presented at Midwest IO: https://www.youtube.com/watch?v=VC99D_Vf8IY Presented at Cocoaconf: http://cocoaconf.com/speaker/viewDetails/31 I work at Twitch (previously at Jive Software, Asynchrony, and Cerner).

Updated on June 19, 2022

Comments

  • user963601
    user963601 almost 2 years

    When I call WebView#loadUrl I expect that I should only get a single WebViewClient#onPageFinished call and no WebViewClient#shouldOverrideUrlLoading call. However, I get a WebViewClient#shouldOverrideUrlLoading (which I implement by always calling WebView#loadUrl and returning true) and then two WebViewClient#onPageFinished calls with the same URL.

    The page I'm loading uses a lot of ajax requests. Do ajax requests invoke the WebViewClient? My page does not have any meta-refreshes in it.

    This is quite frustrating. Am I doing something wrong?

  • user963601
    user963601 about 8 years
    Thanks for the answer. I don't even have access to the server anymore, so I can't test it under the same conditions. Also, I'm sure WebView's behavior has changed in the years since I posted. It'll probably be a while beofr I can verify that this is correct.
  • Pedro Teran
    Pedro Teran almost 8 years
    @heath_borders do you know what's exactly happening inside the webview, I'm looking into it, since I'm having problems due to multiple calls to onPageFinished.