Android: How to check for successful load of url when using webview.loadUrl

后端 未结 4 1890
旧巷少年郎
旧巷少年郎 2020-12-16 16:25

In webview android I am trying to load a url and in order to check if the load of this url is done successfully (internet connection was available, the server was up etc) I

相关标签:
4条回答
  • 2020-12-16 16:30

    You can check if a URL is loaded successfully by using onProgressChanged()

    mWebView.setWebChromeClient(new WebChromeClient() {
    
             public void onProgressChanged(WebView view, int progress) {
                    progressBar.setProgress(progress);
                    if (progress == 100) {
                        //your url is loaded successfully 
                    }
                }
        });
    
    0 讨论(0)
  • 2020-12-16 16:37
    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);
            }
    }
    

    and then you can do

    webView.setWebViewClient(new AppWebViewClient());
    

    For the error part you can override the onReceivedError method

    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            // TODO Auto-generated method stub
            super.onReceivedError(view, errorCode, description, failingUrl);
    }
    
    0 讨论(0)
  • 2020-12-16 16:45

    Here is what I came up with, it works like a charm.

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

    It will also work great if you add some kind of a refresh button and then you can call the code above inside a function to try again.

    0 讨论(0)
  • 2020-12-16 16:47

    Unfortunately, currently there is no easy way in WebView to ensure that everything on the page has been loaded successfully. We are hoping for a better API to come up in future version. Let me explain what you can do now.

    First of all, in order to detect any problems that prevent WebView from making a connection to the server for loading your main page (e.g. bad domain name, I/O error, etc.), you should use WebViewClient.onReceivedError callback as other people correctly suggest:

    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());
    

    If the server connection was successful, and the main page was retrieved and parsed, you will receive WebView.onPageFinished callback, so you also need to have this in your WebViewClient subclass:

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

    The caveat here is that if you have received an HTTP error from the server (e.g. a 404 or a 500 error), this callback will be called anyway, it's just the content that you will get in your WebView will be a server error page. People suggest different ways of how to deal with it, see the answers here: How can I check from Android WebView if a page is a "404 page not found"? Basically, it really depends on what you expect to be a "good" page and a "error" page. Unfortunately, there is currently no way for the app to get the HTTP response code from WebView.

    The callbacks WebViewClient.onPageStarted and WebViewClient.onProgressChanged are only useful if you want to draw a progress bar as you are loading the page.

    Also note that the way of overriding WebViewClient.shouldOverrideUrlLoading that people usually suggest is not correct:

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

    What few developers realize is that the callback is also called for subframes with non-https schemes. If you'll encounter something like <iframe src='tel:1234'>, you will end up executing view.loadUrl('tel:1234') and your app will show an error page, since WebView doesn't know how to load a tel: URL. It is recommended to simply return false from the method, if you want WebView to do the loading:

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

    This doesn’t mean you should not call WebView.loadUrl from shouldOverrideUrlLoading at all. The specific pattern to avoid is doing so unconditionally for all URLs.

    0 讨论(0)
提交回复
热议问题