88 votes

Empêcher le WebView d'afficher "page Web non disponible".

J'ai une application qui fait un usage intensif d'une WebView. Lorsque l'utilisateur de cette application n'a pas de connexion Internet, une page indiquant "page web non disponible" et divers autres textes s'affichent. Existe-t-il un moyen de ne pas afficher ce texte générique dans mon WebView ? J'aimerais fournir ma propre gestion des erreurs.

private final Activity activity = this;

private class MyWebViewClient extends WebViewClient
 public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
  // I need to do something like this:
  activity.webView.wipeOutThePage();
  activity.myCustomErrorHandling();
  Toast.makeText(activity, description, Toast.LENGTH_LONG).show();
 }
}

J'ai découvert WebView->clearView n'efface pas vraiment la vue.

3 votes

Pourquoi ne pas vérifier la connexion Internet avant d'afficher le WebView et, s'il n'y a pas d'accès Internet, ne pas afficher le WebView et afficher une alerte ou un toast sans message Internet ?

0 votes

@JoJo pouvez-vous cocher une réponse comme correcte ? probablement la mienne :P

103voto

SnowboardBruin Points 1788

Tout d'abord, créez votre propre page d'erreur en HTML et placez-la dans votre dossier de ressources, appelons-la myerrorpage.html. Puis avec onReceivedError :

mWebView.setWebViewClient(new WebViewClient() {
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        mWebView.loadUrl("file:///android_asset/myerrorpage.html");

    }
});

28 votes

L'ancienne page d'erreur "Webpage not loaded" s'affiche pendant une fraction de seconde avant d'être remplacée par la page d'erreur personnalisée provenant des actifs.

1 votes

D'accord avec Cheenu. Il doit y avoir une meilleure solution.

3 votes

1. Vous pourriez charger le contenu web pendant que le WebView est invisible (et peut-être afficher un badge de progression par-dessus) et le montrer si la page est chargée avec succès/charger "myerrorpage.html" en cas d'erreur. 2. Vous devez savoir que onReceiveError sera déclenché s'il y a des problèmes de chargement de la page OU un problème dans le JS qui s'exécute après le chargement de la page (comme les fonctions jQuery qui s'exécutent dans l'événement document.ready()). Navigateur de bureau - permet les erreurs JS sans en avertir l'utilisateur, comme le font les navigateurs mobiles.

11voto

cmcromance Points 668

Finalement, j'ai résolu ce problème. (Ca marche jusqu'à maintenant..)

Ma solution est la suivante...

  1. Préparez la mise en page pour qu'elle s'affiche lorsqu'une erreur se produit au lieu de la page Web (un sale message "page non trouvée"). La mise en page comporte un bouton, "RELOAD", et quelques messages d'orientation.

  2. Si une erreur s'est produite, rappelez-vous en utilisant le booléen et montrez la mise en page que nous avons préparée.

  3. Si l'utilisateur clique sur le bouton "RELOAD", définissez mbErrorOccured sur false. Et définissez mbReloadPressed sur true.

  4. si mbErrorOccured est false et mbReloadPressed est true, cela signifie que le webview a chargé la page avec succès. Parce que si l'erreur se produit à nouveau, mbErrorOccured sera mis à true sur onReceivedError(...)

Voici ma source complète. Regardez ça.

public class MyWebViewActivity extends ActionBarActivity implements OnClickListener {

    private final String TAG = MyWebViewActivity.class.getSimpleName();
    private WebView mWebView = null;
    private final String URL = "http://www.google.com";
    private LinearLayout mlLayoutRequestError = null;
    private Handler mhErrorLayoutHide = null;

    private boolean mbErrorOccured = false;
    private boolean mbReloadPressed = false;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview);

        ((Button) findViewById(R.id.btnRetry)).setOnClickListener(this);
        mlLayoutRequestError = (LinearLayout) findViewById(R.id.lLayoutRequestError);
        mhErrorLayoutHide = getErrorLayoutHideHandler();

        mWebView = (WebView) findViewById(R.id.webviewMain);
        mWebView.setWebViewClient(new MyWebViewClient());
        WebSettings settings = mWebView.getSettings();
        settings.setJavaScriptEnabled(true);
        mWebView.setWebChromeClient(getChromeClient());
        mWebView.loadUrl(URL);
    }

    @Override
    public boolean onSupportNavigateUp() {
        return super.onSupportNavigateUp();
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();

        if (id == R.id.btnRetry) {
            if (!mbErrorOccured) {
                return;
            }

            mbReloadPressed = true;
            mWebView.reload();
            mbErrorOccured = false;
        }
    }

    @Override
    public void onBackPressed() {
        if (mWebView.canGoBack()) {
            mWebView.goBack();
            return;
        }
        else {
            finish();
        }

        super.onBackPressed();
    }

    class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return super.shouldOverrideUrlLoading(view, url);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
        }

        @Override
        public void onLoadResource(WebView view, String url) {
            super.onLoadResource(view, url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            if (mbErrorOccured == false && mbReloadPressed) {
                hideErrorLayout();
                mbReloadPressed = false;
            }

            super.onPageFinished(view, url);
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            mbErrorOccured = true;
            showErrorLayout();
            super.onReceivedError(view, errorCode, description, failingUrl);
        }
    }

    private WebChromeClient getChromeClient() {
        final ProgressDialog progressDialog = new ProgressDialog(MyWebViewActivity.this);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(false);

        return new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
            }
        };
    }

    private void showErrorLayout() {
        mlLayoutRequestError.setVisibility(View.VISIBLE);
    }

    private void hideErrorLayout() {
        mhErrorLayoutHide.sendEmptyMessageDelayed(10000, 200);
    }

    private Handler getErrorLayoutHideHandler() {
        return new Handler() {
            @Override
            public void handleMessage(Message msg) {
                mlLayoutRequestError.setVisibility(View.GONE);
                super.handleMessage(msg);
            }
        };
    }
}

Addition:Voici la mise en page....

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rLayoutWithWebView"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<WebView
    android:id="@+id/webviewMain"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<LinearLayout
    android:id="@+id/lLayoutRequestError"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:background="@color/white"
    android:gravity="center"
    android:orientation="vertical"
    android:visibility="gone" >

    <Button
        android:id="@+id/btnRetry"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:minWidth="120dp"
        android:text="RELOAD"
        android:textSize="20dp"
        android:textStyle="bold" />
</LinearLayout>

0 votes

Pouvez-vous partager votre fichier de ressources ? Je suis un débutant.

0 votes

@RajanRawal J'ai édité et ajouté l'exemple de mise en page :)

0 votes

Je ne vois pas de barre de progression, mais je peux y voir du code. :-(

7voto

Torid Points 2821

Consultez la discussion à WebView Android onReceivedError() . C'est assez long, mais le consensus semble être que a) vous ne pouvez pas empêcher la page "web page not available" d'apparaître, mais b) vous pouvez toujours charger une page vide après avoir reçu un onReceivedError.

0 votes

Ces gars-là parlent de onReceivedError pas de déclenchement du tout. Il se déclenche correctement dans mon code lorsqu'il n'y a pas de connexion Internet.

2voto

Ravi Vyas Points 7149

Vous pourriez utiliser un GET pour obtenir le contenu de la page, puis afficher ces données à l'aide de la fonction Webview De cette façon, vous n'avez pas besoin d'appeler plusieurs serveurs. Vous pouvez aussi utiliser Javascript pour vérifier le DOM pour la validité de l'objet.

0 votes

c'est une bonne idée, mais c'est vraiment dommage que nous devions faire quelque chose comme ça ...

2voto

Matt Points 466

Peut-être ai-je mal compris la question, mais on dirait que vous dites que vous obtenez le rappel d'erreur reçue, et vous demandez simplement quelle est la meilleure façon de ne pas montrer l'erreur ? Pourquoi ne pas simplement supprimer la vue Web de l'écran et/ou afficher une autre vue par-dessus ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X