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
?
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());
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;
}
}
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 .
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;
}
});
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.
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");
}
}
}