Here is my code
public class Main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WebView webView = (WebView)findViewById(R.id.webView);
// Assign webclient.
webView.setWebViewClient(new WebViewClient( ) {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.d("TAG", url);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Log.d("TAG", "failed: " + failingUrl + ", error code: " + errorCode + " [" + description + "]");
}
});
webView.loadUrl("http://m.vooglemoogle.com" );
}
}
Results in the following log:
03-29 13:40:27.005: DEBUG/TAG(10948): http://m.vooglemoogle.com/
03-29 13:40:27.599: DEBUG/TAG(10948): failed: http://m.vooglemoogle.com/, error code: -2[The URL could not be found.]
03-29 13:40:27.607: DEBUG/TAG(10948): http://m.vooglemoogle.com/
Note another call to onPageStarted( ) ... Does anyone know the reason behind this? cheers!
I encountered the same problem while testing my app on an AVD with API 7 (not sure if this is relevant but in any case).
I noticed that the exact sequence of callbacks is the following:
onPageStarted() // url = non-existing url
onLoadResource() // url = non-existing url
onReceivedError() // url = non-existing url
onPageStarted() // url = non-existing url
onLoadResource() // url = file://android_assed/webkit/android-weberror.png
onPageFinished() // url = non-existing url
So I guess the loading of the Android "Web page not available" page is triggering the second onPageStarted call.
I struggled with this as well, but I think I've worked around it. Basically I set a flag on error to keep the client from processing any more callbacks. The flag gets reset when I call a method in the activity to try the load again. Here is some sample code from a gist I created https://gist.github.com/museofwater/6373048
public class AsyncMultiplayerSetupActivity extends Activity {
private static final String TAG = AsyncMultiplayerSetupActivity.class.getName();
public static final String UTF_8 = "UTF-8";
private WebView wvSignin;
private String url = "http://localhost:9000/signin";
private ProgressDialog progressLoadUrl;
private SigninWebViewClient webViewClient;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
registerUser(url);
}
private void registerUser(String url) {
webViewClient = new SigninWebViewClient(getResources().getInteger(R.integer.timeout));
setContentView(R.layout.setup);
wvSignin = (WebView)findViewById(R.id.wvSignin);
wvSignin.getSettings().setJavaScriptEnabled(true);
wvSignin.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
wvSignin.setWebViewClient(webViewClient);
loadUrl(url);
}
private void loadUrl(String url) {
if (!NetworkUtil.checkNetwork(this)) {
setSigninFailureResult();
}
// Show progress
progressLoadUrl =
ProgressDialog.show(this, getString(R.string.CONNECTING_TITLE),
getString(R.string.CONNECTING_MSG));
webViewClient.prepareToLoadUrl();
wvSignin.loadUrl(url);
}
private void setSigninFailureResult() {
setResult(getResources().getInteger(R.integer.RESPONSE_FAILED_CODE));
finish();
}
private void setSigninResult() {
setResult(getResources().getInteger(R.integer.RESPONSE_OK_CODE));
}
private class SigninWebViewClient extends WebViewClient {
/**
* Timeout for page load in seconds
*/
private int timeout;
private String urlLoading;
boolean pageLoaded = false;
// Flag to instruct the client to ignore callbacks after an error
boolean hasError = false;
private Handler timeoutHandler;
private AlertDialog alertDialog;
private SigninWebViewClient(int timeout) {
this.timeout = timeout;
timeoutHandler = new Handler();
}
// Called by activity before requesting load of a url
private void prepareToLoadUrl() {
this.hasError = false;
this.pageLoaded = true;
this.urlLoading = null;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
if (hasError) {
return;
}
urlLoading = url;
// timeout has expired if this flag is still set when the message is handled
pageLoaded = false;
Runnable run = new Runnable() {
public void run() {
// Do nothing if we already have an error
if (hasError) {
return;
}
// Dismiss any current alerts and progress
dismissProgress();
dismissErrorAlert();
if (!pageLoaded) {
showTimeoutAlert();
}
}
};
timeoutHandler.postDelayed(run, this.timeout*1000);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// Ignore future callbacks because the page load has failed
hasError = true;
dismissProgress();
showServerErrorAlert();
}
@Override
public void onPageFinished(WebView view, String url) {
if (hasError) {
return;
}
pageLoaded = true;
dismissProgress();
dismissErrorAlert();
urlLoading = null;
// Do whatever processing you need to on page load here
}
private void showTimeoutAlert() {
showErrorAlert(R.string.TIMEOUT_TITLE, R.string.TIMEOUT_MSG);
}
private void showServerErrorAlert() {
showErrorAlert(R.string.SERVER_ERROR_TITLE,R.string.SERVER_ERROR_MSG);
}
private void showErrorAlert(int titleResource, int messageResource) {
AlertDialog.Builder builder = new AlertDialog.Builder(AsyncMultiplayerSetupActivity.this);
// Add the buttons
builder.setTitle(titleResource)
.setMessage(messageResource)
.setPositiveButton(R.string.RETRY, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Try to load url again
loadUrl(urlLoading);
dialog.dismiss();
}
});
builder.setNegativeButton(R.string.CANCEL, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
setSigninFailureResult();
dialog.cancel();
}
});
// Create the AlertDialog
alertDialog = builder.create();
alertDialog.show();
}
private void dismissProgress() {
if (progressLoadUrl != null && progressLoadUrl.isShowing()) {
progressLoadUrl.dismiss();
}
}
private void dismissErrorAlert() {
if (alertDialog != null && alertDialog.isShowing()) {
alertDialog.dismiss();
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With