¿Puedo configurar el tiempo de espera de getaddrinfo en Android para DefaultHttpClient?

En una aplicación para Android, intento probar que el usuario tiene una conexión a Internet activa. Si usted está interesado, hay algunos antecedentes en una pregunta anterior Detección de conectividad de red limitada en Android?

El código es básicamente como:

try { HttpParams myParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(myParams, 10000); HttpConnectionParams.setSoTimeout(myParams, 10000); httpClient = new DefaultHttpClient(myParams); request = new HttpHead(url); response = httpClient.execute(request); statusCode = response.getStatusLine().getStatusCode(); if (statusCode != 200) { return false; } return true; } catch(Exception e) { return false; } 

Puedo controlar los tiempos de espera para la conexión y el zócalo usando HttpConnectionParams. Pero, si mi dispositivo está conectado a Wifi, pero el wifi no tiene acceso a Internet, el error que estoy recibiendo en la excepción es:

libcore.io.GaiException: getaddrinfo falló: EAI_NODATA (ninguna dirección asociada con el nombre de host)

No se puede resolver el host "www.example.com": ninguna dirección asociada con el nombre de host

Lo que parece que se agotó en una búsqueda de DNS. ¿Puedo controlar el tiempo de espera de la búsqueda de DNS? httpClient.execute está tardando unos 45 segundos en fallar con la excepción indicada anteriormente. Me gustaría que renunciara antes.

Hice un poco de tarea y parece que no se puede ajustar el tiempo de espera de búsqueda de DNS. Por lo tanto, pensé que un mejor enfoque sería una búsqueda explícita de DNS para poder controlarlo (y espero tener el resultado en caché para acelerar el próximo intento). Así que me llevó a la simple:

 InetAddress addr = InetAddress.getByName(hostname); 

pero esto también tenía un tiempo de espera de 45 segundos. Otros habían mencionado que no había control del tiempo de espera para getByName () . Por último, tropecé con una solución simple, acaba de lanzar la búsqueda en un hilo separado y gestionar su propio tiempo de espera. Esta publicación de blog muestra esto bastante bien.

 private static boolean testDNS(String hostname) { try { DNSResolver dnsRes = new DNSResolver(hostname); Thread t = new Thread(dnsRes); t.start(); t.join(1000); InetAddress inetAddr = dnsRes.get(); return inetAddr != null; } catch(Exception e) { return false; } } private static class DNSResolver implements Runnable { private String domain; private InetAddress inetAddr; public DNSResolver(String domain) { this.domain = domain; } public void run() { try { InetAddress addr = InetAddress.getByName(domain); set(addr); } catch (UnknownHostException e) { } } public synchronized void set(InetAddress inetAddr) { this.inetAddr = inetAddr; } public synchronized InetAddress get() { return inetAddr; } } 

Usando esto puedo primero probar si el dispositivo puede resolver el nombre del anfitrión, entonces si él acertado a la prueba de conectividad completa.

  • Comparación de las bibliotecas de redes Android: OkHTTP, Retrofit y Volley
  • ¿Cómo enviar un montón de coordenadas (x, y) a través de la red?
  • Android estadísticas 3g de tráfico para cada APP, ¿cómo?
  • ¿Cómo detectar si el sistema está conectado a wifi ad hoc o de infraestructura?
  • Redes Android
  • ¿Cómo hacer que el dispositivo Android mantenga una conexión TCP a Internet sin bloqueo de la sesión?
  • Cómo enviar el archivo binario y el texto usando el mismo socket
  • Crear un NinePatch / NinePatchDrawable en tiempo de ejecución
  • No se puede hacer ping / comunicarse con dispositivos Android en la misma red
  • ¿Cómo maneja Android Volley temporalmente la pérdida de conexión de red?
  • Android: el fragmento es demasiado lento al cargar
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.