I'm using Twitter4J and a WebView. A circular progress bar (spinner) is displayed in onPageStarted. This dialog is hidden in onPageFinished.
The problem is that the spinner never disappears. Adding logging statements to onPageStarted and onPageFinished, this is what I see (name changed):
loading url: http://twitter.com/xyz
finished loading url: http://twitter.com/xyz
loading url: http://mobile.twitter.com/xyz
loading url: https://mobile.twitter.com/xyz
The last two URLs NEVER callback to onPageFinished.
Although I can write an ugly hack to only display the loading dialog when the first URL is loaded, that doesn't solve the problem--then the spinner disappears before the content actually finishes loading.
From reading around on StackOverflow I gather that detecting when a WebView has truly finished loading can be problematic, and have not seen a very good solution to that issue. However, I'm开发者_高级运维 just hoping that someone familiar with displaying Twitter feeds in WebViews in Android apps knows how to tell when it finishes loading. I'm really surprised onPageFinished is not getting called correctly, as the page looks fulled loaded.
I finally found the answer! There are two steps to be added.
Use the best mobile URL. If you enter a URL that you would use on the desktop, there are several redirects. This slows down the page loading, confuses the webview, and then onPageStarted() and onPageFinished() both run multiple times. To find the mobile URL, simply enter the URL in a browser, let it finish its redirects and loading, then take whatever URL it ends up at and use that in your code.
Use webview.getSettings().setUserAgentString("whatever"). The exact user agent string is irrelevant; you just have to set it, or else the webviews are not loaded properly. Kudos to gid for giving this response at can't open twitter url in android webview (sorry, I don't have enough reputation to upvote him on that thread).
As long as I do both these things, it works perfectly--I remove the spinner in onPageFinished and the app acts as a user expects.
People who still have trouble with it may try:
webview.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
Log.d(TAG, "progress updated to " + newProgress);
}
});
I didn't have much luck with reliably counting on this eventually reporting progress of 100, but someone else might.
精彩评论