2010-06-19 6 views
41

J'écris une application qui se connecte à un service web et je ne veux pas qu'il attende trop longtemps s'il ne peut pas obtenir une connexion. Je définis donc la connectionTimeout des httpparams. Mais cela ne semble avoir aucun effet.Http connexion timeout sur Android ne fonctionne pas

Pour tester, j'éteins temporairement mon WLAN. L'application essaie de se connecter pendant un certain temps (bien plus que les 3 secondes que je veux), puis lance 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 des idées ce que je manqué?

Répondre

74

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 ensuite attraper un ConnectTimeoutException possible.

+3

Comment le système est-il informé du délai d'attente et quelle exception gérer? – vokilam

+1

@VokilaM: Je viens d'éditer ma réponse. – Cristian

+3

Je reçois toujours une UnknownHostException après 30+ secondes. Dans ce cas, l'appareil est connecté à un routeur wifi mais il n'y a pas d'accès internet. Toute idée de comment faire cet appel gérer cela? Sinon, je pourrais revenir à une minuterie externe ... :( – hooby3dfx

1

Cette méthode fonctionne pour moi:

AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(endpoint, 3000) ; 
0
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); 
// Set the default socket timeout (SO_TIMEOUT) 
+0

Ceci n'est pas une réponse à la question, car cet appel de méthode fait déjà partie du code ci-dessous; * un autre conseil *: utilisez le formatage de code pour une meilleure présentation ... – Trinimon

9

Avec la solution marquée Je reçois encore 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 consistait à lancer une tâche asynchrone qui tentera simplement de résoudre le nom d'hôte. L'appel de blocage vérifie toutes les 250 ms pour voir s'il a réussi, et après 4 secondes, il annule la tâche et revient.

C'est ce que je l'ai fait pour le résoudre:

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, on appelle cela au début de la fonction:

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

C'est ce que je cherchais. Merci mon pote! –

2

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

Le problème peut être dans le client HTTP Apache. Voir HTTPCLIENT-1098. Fixé en 4.1.2.

L'exception de délai d'attente tente d'inverser DNS l'adresse IP, à des fins de consignation. Cela prend un temps supplémentaire jusqu'à ce que l'exception soit réellement déclenchée.