Java – can I set getaddrinfo timeout for defaulthttpclient in Android?
In the Android application, I try to test whether the user has an available Internet connection If you are interested, you can answer the previous question, detecting limited network connectivity in Android? Find some background knowledge in
The code is basically like:
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; }
I can use httpconnectionparams to control the timeout of connection and socket However, if my device is connected to WiFi but WiFi has no internet access, the error I get in the exception is:
It looks like it timed out on DNS lookup Can I control the timeout of DNS lookup? httpClient. Execute takes about 45 seconds to fail, except for the above I hope it can give up early
Solution
I did some homework. It seems that you can't adjust the DNS lookup timeout Therefore, I think it's better to explicit DNS lookup so that I can control it (and want to cache the results to speed up the next attempt) This makes me simple:
InetAddress addr = InetAddress.getByName(hostname);
But there is also a 45 second timeout Others mentioned no control of the timeout for getbyname() Finally, I stumbled upon a simple solution to start finding and managing my own timeout in a separate thread This blog post illustrates this very well
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; } }
Using this, I can first test whether the device can resolve the host name, and then test whether the full connection test is successful