42 votes

Le délai de connexion Http sur Android ne fonctionne pas

J'écris une application qui se connecte à un webservice et je ne veux pas qu'elle attende trop longtemps si elle n'arrive pas à se connecter. J'ai donc réglé le connectionTimeout des httpparams. Mais cela ne semble pas avoir d'effet.

Pour tester, j'ai désactivé temporairement mon WLAN. L'application essaie de se connecter pendant un certain temps (bien plus que les 3 secondes que je souhaite) et lève une UnknownHostException.

Voici mon code :

try{
    HttpClient httpclient = new DefaultHttpClient();
    HttpParams params = httpclient.getParams();
    HttpConnectionParams.setConnectionTimeout(params, 3000);
    HttpConnectionParams.setSoTimeout(params, 3000);

    httppost = new HttpPost(URL);
    StringEntity se = new StringEntity(envelope,HTTP.UTF_8);
    httppost.setEntity(se);
    //Code stops here until UnknownHostException is thrown.
    BasicHttpResponse httpResponse = (BasicHttpResponse) httpclient.execute(httppost);

    HttpEntity entity = httpResponse.getEntity();
    return entity;

}catch (Exception e){
    e.printStackTrace();
}

Quelqu'un a une idée de ce que j'ai manqué ?

74voto

Cristian Points 92147

Essayez de le faire de cette façon :

HttpPost httpPost = new HttpPost(url);
StringEntity se = new StringEntity(envelope,HTTP.UTF_8);
httpPost.setEntity(se);

HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT) 
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 3000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
BasicHttpResponse httpResponse = (BasicHttpResponse)  httpClient.execute(httpPost);

HttpEntity entity = httpResponse.getEntity();
return entity;

Vous pouvez alors attraper un éventuel ConnectTimeoutException .

9voto

hooby3dfx Points 459

Avec la solution indiquée, je reçois toujours une UnknownHostException après plus de 30 secondes. Dans ce cas, l'appareil est connecté à un routeur wifi mais il n'y a pas d'accès à Internet.

L'approche adoptée a été de lancer une AsyncTask qui va simplement tenter de résoudre le nom d'hôte. L'appel bloquant vérifie toutes les 250 ms s'il a réussi, et après 4 secondes, il annule la tâche et revient.

Voici ce que j'ai fait pour résoudre ce problème :

private boolean dnsOkay = false;
private static final int DNS_SLEEP_WAIT = 250;
private synchronized boolean resolveDns(){

    RemoteDnsCheck check = new RemoteDnsCheck();
    check.execute();
    try {
        int timeSlept = 0;
        while(!dnsOkay && timeSlept<4000){
            //Log.d("RemoteDnsCheck", "sleeping");
            Thread.sleep(DNS_SLEEP_WAIT);
            timeSlept+=DNS_SLEEP_WAIT;
            //Log.d("RemoteDnsCheck", "slept");
        }
    } catch (InterruptedException e) {

    }

    if(!dnsOkay){
        Log.d("resolveDns", "cancelling");
        check.cancel(true);
        Log.d("resolveDns", "cancelled");
    }
    return dnsOkay;
}

private class RemoteDnsCheck extends AsyncTask<Void, Void, Void>{

    @Override
    protected Void doInBackground(Void... params) {
        try {
            Log.d("RemoteDnsCheck", "starting");
            dnsOkay = false;
            InetAddress addr = InetAddress.getByName(baseServiceURL);
            if(addr!=null){
                Log.d("RemoteDnsCheck", "got addr");
                dnsOkay = true;
            }
        } catch (UnknownHostException e) {
            Log.d("RemoteDnsCheck", "UnknownHostException");
        }
        return null;
    }

}

Ensuite, chaque fois que je veux faire un appel web, il est appelé au début de la fonction :

    if(!resolveDns()){
        return null;
    }

3voto

user2609238 Points 11

Voir : http://stackoverflow.com/a/20031077/2609238

Le problème peut provenir du client HTTP Apache. Voir HTTPCLIENT-1098. Corrigé dans la version 4.1.2.

L'exception au délai d'attente tente d'inverser le DNS de l'IP, à des fins de journalisation. Cela prend un temps supplémentaire jusqu'à ce que l'exception soit effectivement déclenchée.

1voto

Jr. Points 44

Cette méthode fonctionne pour moi :

AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport( endpoint, 3000) ;

0voto

user2198255 Points 1
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)

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