加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 我可以在Android中为DefaultHttpClient设置getaddrinfo

发布时间:2020-12-15 04:12:42 所属栏目:Java 来源:网络整理
导读:在 Android应用程序中,我试图测试用户是否有可用的Internet连接.如果您有兴趣,可以在之前的问题 Detecting limited network connectivity in Android?中找到一些背景知识 代码基本上就像: try { HttpParams myParams = new BasicHttpParams(); HttpConnecti
在 Android应用程序中,我试图测试用户是否有可用的Internet连接.如果您有兴趣,可以在之前的问题 Detecting limited network connectivity in 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;
}

我可以使用HttpConnectionParams控制Connection和Socket的超时.但是,如果我的设备连接到Wifi,但wifi没有Internet访问,我在异常中得到的错误是:

libcore.io.GaiException: getaddrinfo failed: EAI_NODATA (No address
associated with hostname)

Unable to resolve host “www.example.com”: No address associated with
hostname

看起来它在DNS查找上超时了.我可以控制DNS查找的超时吗? httpClient.execute大约需要45秒才能失败,但上述情况除外.我希望它能早点放弃.

解决方法

我做了一些功课,似乎你无法调整DNS查找超时.因此,我认为更好的方法是显式DNS查找,以便我可以控制它(并希望缓存结果以加快下一次尝试).这让我变得简单:

InetAddress addr = InetAddress.getByName(hostname);

但这也有45秒的超时.其他人提到有no control of the timeout for getByName().最后,我偶然发现了一个简单的解决方案,只需在一个单独的线程中启动查找并管理自己的超时. This blog post很好地说明了这一点.

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;
    }
}

使用这个我可以先测试设备是否可以解析主机名,然后测试是否成功进行完全连接测试.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读