【问题标题】:Android: How to check for successful load of url when using webview.loadUrlAndroid:使用 webview.loadUrl 时如何检查 url 是否成功加载
【发布时间】:2015-02-07 18:26:46
【问题描述】:

在 webview android 中,我试图加载一个 url,为了检查这个 url 的加载是否成功(互联网连接可用,服务器已启动等)我的印象是 webview.loadUrl 会抛出例外,但错误!正如here 中明确指出的那样,“不会引发异常”。

那么我如何检查 webview.loadUrl 是否失败?

【问题讨论】:

  • 如果它有助于解决您的问题,您能否将答案标记为已接受。谢谢
  • @manishkumar 当然,请给我时间测试一下

标签: android webview android-webview


【解决方案1】:

不幸的是,目前在 WebView 中没有简单的方法来确保页面上的所有内容都已成功加载。我们希望在未来的版本中出现更好的 API。让我解释一下你现在可以做什么。

首先,为了检测任何阻止 WebView 连接到服务器以加载您的主页的问题(例如,错误的域名、I/O 错误等),您应该使用WebViewClient.onReceivedError 回调正如其他人正确建议的那样:

public class MyWebViewClient extends WebViewClient {
    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        // Make a note about the failed load.
    }
}
myWebView.setWebViewClient(new MyWebViewClient());

如果服务器连接成功,并且主页面被检索和解析,你会收到WebView.onPageFinished回调,所以你还需要在你的WebViewClient子类中有这个:

public class MyWebViewClient extends WebViewClient {
    ...
    @Override
    public void onPageFinished(WebView view, String url) {
        // Make a note that the page has finished loading.
    }
    ...
}

这里需要注意的是,如果您从服务器收到 HTTP 错误(例如 404 或 500 错误),无论如何都会调用此回调,它只是您将在 WebView 中获得的内容将是服务器错误页面。人们提出了不同的处理方法,请在此处查看答案:How can I check from Android WebView if a page is a "404 page not found"? 基本上,这实际上取决于您期望成为“好”页面和“错误”页面的内容。遗憾的是,应用目前无法从 WebView 获取 HTTP 响应代码。

回调WebViewClient.onPageStartedWebViewClient.onProgressChanged 仅在您想在加载页面时绘制进度条时才有用。

还要注意,人们通常建议的覆盖WebViewClient.shouldOverrideUrlLoading 的方式是不正确的:

public class MyWebViewClient extends WebViewClient {
    ...
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url)         {  
        // !!! DO NOT DO THIS UNCONDITIONALLY !!!
        view.loadUrl(url);
        return true;
    }
    ...
}

很少有开发人员意识到,对于非 https 方案的子帧也会调用回调。如果您遇到类似<iframe src='tel:1234'> 的内容,您最终将执行view.loadUrl('tel:1234'),并且您的应用程序将显示错误页面,因为WebView 不知道如何加载tel: URL。 如果您希望 WebView 进行加载,建议简单地从方法中返回 false:

public class MyWebViewClient extends WebViewClient {
    ...

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url)         {
        // Returning 'false' unconditionally is fine.
        return false;
    }
    ...
}

这并不意味着您根本不应该从shouldOverrideUrlLoading 调用WebView.loadUrl。要避免的特定模式是对所有 URL 无条件地这样做。

【讨论】:

  • onRecievedError() 中,您可以检查失败的 url 是否等于您加载到 WebView 中的原始 url,并确定主文档是否尚未加载。
  • 当然! onPageFinished 和其他回调也是如此。
  • onReceivedError 未被调用。目标 API 级别
  • @Michael 如果您的应用希望在旧版本上运行,那么使用旧版本的 API 没有问题。
【解决方案2】:
public class AppWebViewClient extends WebViewClient {

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            // TODO Auto-generated method stub
            super.onPageStarted(view, url, favicon);
            setProgressBar(true);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            //Page load finished
            super.onPageFinished(view, url);
            setProgressBar(false);
        }
}

然后你就可以了

webView.setWebViewClient(new AppWebViewClient());

对于错误部分,您可以覆盖onReceivedError 方法

@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        // TODO Auto-generated method stub
        super.onReceivedError(view, errorCode, description, failingUrl);
}

【讨论】:

  • 我需要为此导入什么?
【解决方案3】:

这是我想出的,它就像一个魅力。

    Boolean failedLoading = false;
    WebView webView = view.findViewById(R.id.webView);
    webView.loadUrl("www.example.com");
    webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (!failedLoading) {
                webView.setVisibility(View.VISIBLE);
                webView.setAlpha(0f);
                ObjectAnimator anim  = ObjectAnimator.ofFloat(webView, "alpha",1f);
                anim.setDuration(500);
                anim.start();
            }
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            super.onReceivedError(view, request, error);
            failedLoading = true;
        }
    });

如果您添加某种刷新按钮,然后您可以在函数中调用上面的代码再试一次,它也会很好用。

【讨论】:

    【解决方案4】:

    您可以使用onProgressChanged()检查URL是否加载成功

    mWebView.setWebChromeClient(new WebChromeClient() {
    
             public void onProgressChanged(WebView view, int progress) {
                    progressBar.setProgress(progress);
                    if (progress == 100) {
                        //your url is loaded successfully 
                    }
                }
        });
    

    【讨论】:

    • 这个不行,即使加载失败,进度也会达到100。 @Mikhail Naganov 的答案可能是最好的。
    • @JonasCz,同意,但是据我所知,当webview加载一个url时,如果网页加载失败,它会直接到100,所以我们可以修改代码,比如if(progress= =99),你说什么?
    • 进度可能不完全是 99,因为它可能从 80 直接跳到 100。(查看 aosp 浏览器中的进度条。)
    • 错误,实际上,如果 url 加载失败,进度会从 10 到 100
    猜你喜欢
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 2011-05-20
    • 2012-01-11
    • 1970-01-01
    相关资源
    最近更新 更多