web-dev-qa-db-fra.com

Définir loadURLTImeOutValue sur WebView

Je travaille avec PhoneGap et Android et j'ai mes fichiers .html et js sur un serveur externe. Lorsque j'utilise le code suivant, l'application charge mes fichiers externes .html et tout fonctionne correctement:

this.setIntegerProperty("loadUrlTimeoutValue", 60000);
this.loadUrl("http://www.myserver.com");

Cependant, lorsque je travaille avec un WebView, je n'arrive pas à définir le loadURLTimeoutValue pour un WebView:

private WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);  

try {
     webView = (WebView) findViewById(R.id.webview);    
     webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
     webView.loadUrl("http://www.myserver.com");     
}

Ça ne marche pas. Comment puis-je définir la valeur de délai d'attente sur la WebView?

21
user989557

Il s'agit d'une solution de contournement pour simuler le comportement décrit. Vous pouvez utiliser un WebViewClient et remplacer la méthode onPageStarted:

public class MyWebViewClient extends WebViewClient {
    boolean timeout;

    public MyWebViewClient() {
        timeout = true;
    }

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(timeout) {
                    // do what you want
                }
            }
        }).start();
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        timeout = false;
    }
}

Si timeout, vous pouvez charger, par exemple, une page d'erreur ...

Pour ajouter la WebViewClient à WebView, procédez comme suit:

webView.setWebViewClient(new MyWebViewClient());
28
Vito Gentile

Je l'ai utilisé pour définir un délai d'expiration pour ma WebView:

public class MyWebViewClient extends WebViewClient {

    boolean timeout = true;

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        Runnable run = new Runnable() {
            public void run() {
                if(timeout) {
                    // do what you want
                    showAlert("Connection Timed out", "Whoops! Something went wrong. Please try again later.");
                }
            }
        };
        Handler myHandler = new Handler(Looper.myLooper());
        myHandler.postDelayed(run, 5000);
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        timeout = false;
    }
}
14
Nick

La façon correcte de modifier le délai d'attente par défaut consiste à utiliser la balise <preference /> dans le fichier config.xml, par exemple: 

<preference name="loglevel" value="DEBUG" />
<preference name="loadUrlTimeoutValue" value="60000" />
<preference name="errorUrl" value="file:///Android_asset/www/connection_error.html" />

Pour plus d'options, reportez-vous à Configuration Android .

6
shimatai
WebView mWebView = findViewById(R.id.web_view);
mWebView.setWebViewClient(new WebViewClient() {
    private volatile boolean timeout;
    private volatile String timeoutOnPageStartedURL;
    private volatile String timeoutCurrentURL;

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

        timeout = true;
        timeoutOnPageStartedURL = url;
        timeoutCurrentURL = view.getUrl();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (timeout) {
                    view.post(new Runnable() {
                        @Override
                        public void run() {
                            String currentURL = view.getUrl();
                            if ((timeoutOnPageStartedURL.hashCode() == currentURL.hashCode()) ||
                                (timeoutCurrentURL.hashCode() == currentURL.hashCode())) {
                                // do what you want with UI   
                            }                                     
                        }
                    });
                }
            }
        }).start();
    }

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

        timeout = false;
    }
});
1
Alexander Savin

Si vous étendez CordovaWebView, ce que vous devriez faire pour obtenir l'API phonegap, vous pouvez simplement utiliser les éléments suivants:

this.getIntent().putExtra("loadUrlTimeoutValue", 60000);

En interne, CordovaWebView implémente un mécanisme de délai d'expiration similaire à ceux proposés dans l'article précédent (délai d'expiration par défaut = 2000).

Notez que ce n’est pas une interface documentée, elle risque donc de casser à l’avenir.

1
bertvh

L’utilisation de la classe Thread me dérange d’appeler la WebView depuis la fonction d’exécution conduira à une exception puisque la WebView est créée et utilisée dans un autre thread ..__ Je l’effectuerais avec une AsyncTask . AsyncTask pour charger un fichier d'erreur dans WebView si le délai d'attente a été atteint. Si la page se charge correctement, j'annule l'AsyncTask . La onPostExecute s'exécute dans le thread d'interface utilisateur, de sorte qu'il n'y a pas de problème de sécurité du thread pour interagir avec la vue Web:

private class CustomWebViewClient extends WebViewClient {
    boolean mPageLoaded;
    final int mTimeoutLength = 20000;
    WebView mView;
    TimeoutCheck timeoutCheckTask;

    public CustomWebViewClient()
    {
        super();
        mPageLoaded = false;
    }

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        mView = view;

        timeoutCheckTask  = new TimeoutCheck();
        timeoutCheckTask.execute(null,null);
    }

    public void onPageFinished(WebView view, String url) {
        mPageLoaded = true;
        timeoutCheckTask.cancel(true);
    }

    private class TimeoutCheck extends AsyncTask<Void, Void, Void> {
        protected Void doInBackground(Void... params) {
            long count = 0;
            while (count < mTimeoutLength)
            {
                try
                {
                    Thread.sleep( 1000 );
                }
                catch ( InterruptedException e )
                {
                    e.printStackTrace();
                }

                // Escape early if cancel() is called
                if (isCancelled()) break;
                count += 1000;
            }
            return null;
        }

        protected void onPostExecute(Void result) {
            if(!mPageLoaded) {
                mbLoadedErrFile = true;
                //load error file into the webview
                mView.loadUrl("file:///Android_asset/url_err_timeout.html");
            }
        }
    }
0
Itamar Kerbel