Android系统时间自动设置NTP服务报错

  • 问题描述:
    在日期和时间中开启自动设置,时间不变,并没有同步到网络时间。

  • 问题查找:
    开始以为是系统默认的ntp服务器有问题,查看后发现使用的是阿里云的NTP服务器ntp2.aliyun.com,我在设备内pin了一下,也是通的。

    然后,查看打印日志,发现报了request time failed: Unable to resolve host "ntp2.aliyun.com" No address associated with hostname的错误,这个是因为通过域名获取地址时报的错。

    通过查询源码,发现报错地方是在SntpClient.javarequestTime方法中,当address = network.getByName(host);捕获到的异常。跟踪SntpClient.java的调用路径:

//java层
NetWork.getByName
InetAddress.getByNameOnNet (Network.java)
Inet6AddressImpl.lookupAllHostAddr
lookupHostByName
//native层
Libcore.os.android_getaddrinfo
Linux_android_getaddrinfo (libcore_io_Linux.cpp)
android_getaddrinfofornet
getaddrinfo
android_getaddrinfofornetcontext (getaddrinfo.c)
android_getaddrinfo_proxy

getaddrinfo后的流程,已有博客做了分析Android libc中dns部分源码分析。而且根据错误打印,可以知道对应的是EAI_NODATA,所以可以顺藤摸瓜去发现主要是在android_getaddrinfo_proxy中,而android_getaddrinfo_proxy是跟netd调用有关。

  • 解決方式:
    因为network.getByName(host)中调用的是InetAddress.getByNameOnNet方法,该方法是基于给定的网络获取域名,第二个参数netid的值可以影响DNS请求包从哪个网卡出去。

    所以,刚开始觉得可能是ip6导致的,因此关闭了ip6的网络,发现没啥效果。可能是其他网卡影响的(我们这里有vpn),不过没有再尝试了。

    最后,就先通过代码优化一下,直接使用InetAddress.getByName方法再次解析一遍。
try {
     address = network.getByName(host);
 } catch (Exception e) {
     if (e.getMessage() != null 
           && e.getMessage().endsWith("No address associated with hostname")) {
         Log.d(TAG, "first request time failed: " + e);
         address = InetAddress.getByName(host);
     }
     if (null == address || null == address.getHostAddress()) {
         throw e;
     }
 }
  • 总结
    总的来说问题是解决了,基本原因也大概了解,通过netid对应的网卡发送请求去获取ip信息失败造成的,InetAddress.getByName中使用的netid和network.getByName使用的netid可能是不一样的(未检测)引起的
    但是,因为没有很深入很深入的去研究,如果有机会,再完善吧。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值