13

这是我的代码

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" );
}



}

结果如下日志:

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/

请注意对 onPageStarted( ) 的另一个调用...有谁知道这背后的原因吗?干杯!

4

3 回答 3

14

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.

于 2011-12-09T11:46:35.857 回答
2

我也为此苦苦挣扎,但我想我已经解决了这个问题。基本上我设置了一个错误标志,以防止客户端处理更多回调。当我在活动中调用方法以再次尝试加载时,该标志会重置。这是我创建的要点的一些示例代码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();
            }
        }
    }
}
于 2013-08-29T00:55:21.267 回答
-2

在android API中,您可以找到注释:

通知主机应用程序页面已开始加载。每次加载主框架时都会调用一次此方法,因此具有 iframe 或框架集的页面将为主框架调用一次 onPageStarted。这也意味着当嵌入框架的内容发生变化时,不会调用 onPageStarted,即单击目标为 iframe 的链接。

这表明它可能是由网页中的“iframe”引起的。

于 2011-11-08T06:22:10.793 回答