Mic*_*evy 4 java networking android http connectivity
在Android应用程序中,我试图测试用户是否有可用的Internet连接.如果您有兴趣,在上一个问题中有一些背景检测Android中有限的网络连接?
代码基本上就像:
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;
}
Run Code Online (Sandbox Code Playgroud)
我可以使用HttpConnectionParams控制Connection和Socket的超时.但是,如果我的设备连接到Wifi,但wifi没有Internet访问,我在异常中得到的错误是:
libcore.io.GaiException:getaddrinfo失败:EAI_NODATA(没有与主机名关联的地址)
无法解析主机"www.example.com":没有与主机名关联的地址
看起来它在DNS查找上超时了.我可以控制DNS查找的超时吗?httpClient.execute大约需要45秒才能失败,但上述情况除外.我希望它能早点放弃.
Mic*_*evy 10
我做了一些功课,似乎你无法调整DNS查找超时.因此,我认为更好的方法是显式DNS查找,以便我可以控制它(并希望缓存结果以加快下一次尝试).这让我变得简单:
InetAddress addr = InetAddress.getByName(hostname);
Run Code Online (Sandbox Code Playgroud)
但这也有45秒的超时.其他人提到没有控制getByName()的超时.最后,我偶然发现了一个简单的解决方案,只需在一个单独的线程中启动查找并管理自己的超时.这篇博文很好地展示了这一点.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
使用这个我可以先测试设备是否可以解析主机名,然后测试是否成功进行完全连接测试.
归档时间: |
|
查看次数: |
2997 次 |
最近记录: |