web-dev-qa-db-fra.com

Android: comment vérifier le chargement réussi de l'URL lors de l'utilisation de webview.loadUrl

Dans webview Android J'essaie de charger une URL et afin de vérifier si le chargement de cette URL s'est fait avec succès (la connexion Internet était disponible, le serveur était en place, etc.), j'avais l'impression que webview.loadUrl lèverait des exceptions, mais faux! comme cela est explicitement indiqué dans ici "une exception ne sera PAS levée".

Alors, comment puis-je vérifier si webview.loadUrl n'a pas échoué?

13
C graphics

Malheureusement, il n'existe actuellement aucun moyen simple dans WebView de s'assurer que tout sur la page a été chargé avec succès. Nous espérons qu'une meilleure API arrivera dans la future version. Laissez-moi vous expliquer ce que vous pouvez faire maintenant.

Tout d'abord, afin de détecter tout problème empêchant WebView de se connecter au serveur pour charger votre page principale (par exemple, mauvais nom de domaine, erreur d'E/S, etc.), vous devez utiliser le rappel WebViewClient.onReceivedError comme d'autres le suggèrent correctement:

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

Si la connexion au serveur a réussi et que la page principale a été récupérée et analysée, vous recevrez un rappel WebView.onPageFinished, Vous devez donc également l'avoir dans votre sous-classe WebViewClient:

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

La mise en garde ici est que si vous avez reçu une erreur HTTP du serveur (par exemple une erreur 404 ou 500), ce rappel sera appelé de toute façon, c'est juste le contenu que vous obtiendrez dans votre WebView qui sera une page d'erreur du serveur. Les gens suggèrent différentes façons de le gérer, voir les réponses ici: Comment puis-je vérifier à partir de Android WebView si une page est une "page 404 introuvable"? = Fondamentalement, cela dépend vraiment de ce que vous attendez d'une "bonne" page et d'une page "d'erreur". Malheureusement, il n'y a actuellement aucun moyen pour l'application d'obtenir le code de réponse HTTP de WebView.

Les rappels WebViewClient.onPageStarted Et WebViewClient.onProgressChanged Ne sont utiles que si vous souhaitez dessiner une barre de progression lors du chargement de la page.

Notez également que la façon de remplacer WebViewClient.shouldOverrideUrlLoading Que les gens suggèrent généralement n'est pas correcte:

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

Ce que peu de développeurs réalisent, c'est que le rappel est également appelé pour les sous-trames avec des schémas non https. Si vous rencontrez quelque chose comme <iframe src='tel:1234'>, Vous finirez par exécuter view.loadUrl('tel:1234') et votre application affichera une page d'erreur, car WebView ne sait pas comment charger un tel: URL. Il est recommandé de renvoyer simplement false à partir de la méthode, si vous souhaitez que WebView effectue le chargement:

public class MyWebViewClient extends WebViewClient {
    ...

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

Cela ne signifie pas que vous ne devez pas du tout appeler WebView.loadUrl Depuis shouldOverrideUrlLoading. Le modèle spécifique à éviter le fait sans condition pour toutes les URL.

15
Mikhail Naganov
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);
        }
}

et ensuite vous pouvez faire

webView.setWebViewClient(new AppWebViewClient());

Pour la partie erreur, vous pouvez remplacer la méthode 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
Manish Kumar

Voici ce que j'ai trouvé, fonctionne comme un charme

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

Fonctionne également très bien si vous avez une sorte de bouton d'actualisation, vous pouvez appeler le code ci-dessus dans une fonction pour réessayer :)

1
ueen